blob: 8a73561468663d5747799af92e044770d1e578fd [file] [log] [blame]
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001// Copyright 2011 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
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +000038#include "elements.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000039#include "objects.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000040#include "contexts.h"
41#include "conversions-inl.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000042#include "heap.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000043#include "isolate.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000044#include "property.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000045#include "spaces.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000046#include "v8memory.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000047
kasperl@chromium.org71affb52009-05-26 05:44:31 +000048namespace v8 {
49namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000050
51PropertyDetails::PropertyDetails(Smi* smi) {
52 value_ = smi->value();
53}
54
55
56Smi* PropertyDetails::AsSmi() {
57 return Smi::FromInt(value_);
58}
59
60
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000061PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000062 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000063 return PropertyDetails(smi);
64}
65
66
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000067#define CAST_ACCESSOR(type) \
68 type* type::cast(Object* object) { \
69 ASSERT(object->Is##type()); \
70 return reinterpret_cast<type*>(object); \
71 }
72
73
74#define INT_ACCESSORS(holder, name, offset) \
75 int holder::name() { return READ_INT_FIELD(this, offset); } \
76 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
77
78
79#define ACCESSORS(holder, name, type, offset) \
80 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000081 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000082 WRITE_FIELD(this, offset, value); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000083 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode); \
84 }
85
86
87// GC-safe accessors do not use HeapObject::GetHeap(), but access TLS instead.
88#define ACCESSORS_GCSAFE(holder, name, type, offset) \
89 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
90 void holder::set_##name(type* value, WriteBarrierMode mode) { \
91 WRITE_FIELD(this, offset, value); \
92 CONDITIONAL_WRITE_BARRIER(HEAP, this, offset, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000093 }
94
95
96#define SMI_ACCESSORS(holder, name, offset) \
97 int holder::name() { \
98 Object* value = READ_FIELD(this, offset); \
99 return Smi::cast(value)->value(); \
100 } \
101 void holder::set_##name(int value) { \
102 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
103 }
104
105
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000106#define BOOL_GETTER(holder, field, name, offset) \
107 bool holder::name() { \
108 return BooleanBit::get(field(), offset); \
109 } \
110
111
112#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000113 bool holder::name() { \
114 return BooleanBit::get(field(), offset); \
115 } \
116 void holder::set_##name(bool value) { \
117 set_##field(BooleanBit::set(field(), offset, value)); \
118 }
119
120
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000121bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
122 // There is a constraint on the object; check.
123 if (!this->IsJSObject()) return false;
124 // Fetch the constructor function of the object.
125 Object* cons_obj = JSObject::cast(this)->map()->constructor();
126 if (!cons_obj->IsJSFunction()) return false;
127 JSFunction* fun = JSFunction::cast(cons_obj);
128 // Iterate through the chain of inheriting function templates to
129 // see if the required one occurs.
130 for (Object* type = fun->shared()->function_data();
131 type->IsFunctionTemplateInfo();
132 type = FunctionTemplateInfo::cast(type)->parent_template()) {
133 if (type == expected) return true;
134 }
135 // Didn't find the required type in the inheritance chain.
136 return false;
137}
138
139
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000140bool Object::IsSmi() {
141 return HAS_SMI_TAG(this);
142}
143
144
145bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000146 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000147}
148
149
150bool Object::IsHeapNumber() {
151 return Object::IsHeapObject()
152 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
153}
154
155
156bool Object::IsString() {
157 return Object::IsHeapObject()
158 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
159}
160
161
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000162bool Object::IsSpecObject() {
163 return Object::IsHeapObject()
164 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
165}
166
167
ager@chromium.org870a0b62008-11-04 11:43:05 +0000168bool Object::IsSymbol() {
169 if (!this->IsHeapObject()) return false;
170 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000171 // Because the symbol tag is non-zero and no non-string types have the
172 // symbol bit set we can test for symbols with a very simple test
173 // operation.
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000174 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000175 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
176 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000177}
178
179
180bool Object::IsConsString() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000181 if (!IsString()) return false;
182 return StringShape(String::cast(this)).IsCons();
183}
184
185
186bool Object::IsSlicedString() {
187 if (!IsString()) return false;
188 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000189}
190
191
ager@chromium.org870a0b62008-11-04 11:43:05 +0000192bool Object::IsSeqString() {
193 if (!IsString()) return false;
194 return StringShape(String::cast(this)).IsSequential();
195}
196
197
198bool Object::IsSeqAsciiString() {
199 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000200 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000201 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000202}
203
204
205bool Object::IsSeqTwoByteString() {
206 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000207 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000208 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000209}
210
211
212bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000213 if (!IsString()) return false;
214 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000215}
216
217
218bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000219 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000220 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000221 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000222}
223
224
225bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000226 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000227 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000228 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000229}
230
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000231bool Object::HasValidElements() {
232 // Dictionary is covered under FixedArray.
233 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
234}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000235
ager@chromium.org870a0b62008-11-04 11:43:05 +0000236StringShape::StringShape(String* str)
237 : type_(str->map()->instance_type()) {
238 set_valid();
239 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000240}
241
242
ager@chromium.org870a0b62008-11-04 11:43:05 +0000243StringShape::StringShape(Map* map)
244 : type_(map->instance_type()) {
245 set_valid();
246 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000247}
248
249
ager@chromium.org870a0b62008-11-04 11:43:05 +0000250StringShape::StringShape(InstanceType t)
251 : type_(static_cast<uint32_t>(t)) {
252 set_valid();
253 ASSERT((type_ & kIsNotStringMask) == kStringTag);
254}
255
256
257bool StringShape::IsSymbol() {
258 ASSERT(valid());
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000259 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000260 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000261}
262
263
ager@chromium.org5ec48922009-05-05 07:25:34 +0000264bool String::IsAsciiRepresentation() {
265 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000266 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000267}
268
269
ager@chromium.org5ec48922009-05-05 07:25:34 +0000270bool String::IsTwoByteRepresentation() {
271 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000272 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000273}
274
275
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000276bool String::IsAsciiRepresentationUnderneath() {
277 uint32_t type = map()->instance_type();
278 STATIC_ASSERT(kIsIndirectStringTag != 0);
279 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
280 ASSERT(IsFlat());
281 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
282 case kAsciiStringTag:
283 return true;
284 case kTwoByteStringTag:
285 return false;
286 default: // Cons or sliced string. Need to go deeper.
287 return GetUnderlying()->IsAsciiRepresentation();
288 }
289}
290
291
292bool String::IsTwoByteRepresentationUnderneath() {
293 uint32_t type = map()->instance_type();
294 STATIC_ASSERT(kIsIndirectStringTag != 0);
295 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
296 ASSERT(IsFlat());
297 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
298 case kAsciiStringTag:
299 return false;
300 case kTwoByteStringTag:
301 return true;
302 default: // Cons or sliced string. Need to go deeper.
303 return GetUnderlying()->IsTwoByteRepresentation();
304 }
305}
306
307
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000308bool String::HasOnlyAsciiChars() {
309 uint32_t type = map()->instance_type();
310 return (type & kStringEncodingMask) == kAsciiStringTag ||
311 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000312}
313
314
ager@chromium.org870a0b62008-11-04 11:43:05 +0000315bool StringShape::IsCons() {
316 return (type_ & kStringRepresentationMask) == kConsStringTag;
317}
318
319
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000320bool StringShape::IsSliced() {
321 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
322}
323
324
325bool StringShape::IsIndirect() {
326 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
327}
328
329
ager@chromium.org870a0b62008-11-04 11:43:05 +0000330bool StringShape::IsExternal() {
331 return (type_ & kStringRepresentationMask) == kExternalStringTag;
332}
333
334
335bool StringShape::IsSequential() {
336 return (type_ & kStringRepresentationMask) == kSeqStringTag;
337}
338
339
340StringRepresentationTag StringShape::representation_tag() {
341 uint32_t tag = (type_ & kStringRepresentationMask);
342 return static_cast<StringRepresentationTag>(tag);
343}
344
345
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000346uint32_t StringShape::encoding_tag() {
347 return type_ & kStringEncodingMask;
348}
349
350
ager@chromium.org870a0b62008-11-04 11:43:05 +0000351uint32_t StringShape::full_representation_tag() {
352 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
353}
354
355
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000356STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
357 Internals::kFullStringRepresentationMask);
358
359
ager@chromium.org870a0b62008-11-04 11:43:05 +0000360bool StringShape::IsSequentialAscii() {
361 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
362}
363
364
365bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000366 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000367}
368
369
370bool StringShape::IsExternalAscii() {
371 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
372}
373
374
375bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000376 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000377}
378
379
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000380STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
381 Internals::kExternalTwoByteRepresentationTag);
382
383
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000384uc32 FlatStringReader::Get(int index) {
385 ASSERT(0 <= index && index <= length_);
386 if (is_ascii_) {
387 return static_cast<const byte*>(start_)[index];
388 } else {
389 return static_cast<const uc16*>(start_)[index];
390 }
391}
392
393
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000394bool Object::IsNumber() {
395 return IsSmi() || IsHeapNumber();
396}
397
398
399bool Object::IsByteArray() {
400 return Object::IsHeapObject()
401 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
402}
403
404
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000405bool Object::IsExternalPixelArray() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000406 return Object::IsHeapObject() &&
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000407 HeapObject::cast(this)->map()->instance_type() ==
408 EXTERNAL_PIXEL_ARRAY_TYPE;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000409}
410
411
ager@chromium.org3811b432009-10-28 14:53:37 +0000412bool Object::IsExternalArray() {
413 if (!Object::IsHeapObject())
414 return false;
415 InstanceType instance_type =
416 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000417 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
418 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000419}
420
421
422bool Object::IsExternalByteArray() {
423 return Object::IsHeapObject() &&
424 HeapObject::cast(this)->map()->instance_type() ==
425 EXTERNAL_BYTE_ARRAY_TYPE;
426}
427
428
429bool Object::IsExternalUnsignedByteArray() {
430 return Object::IsHeapObject() &&
431 HeapObject::cast(this)->map()->instance_type() ==
432 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
433}
434
435
436bool Object::IsExternalShortArray() {
437 return Object::IsHeapObject() &&
438 HeapObject::cast(this)->map()->instance_type() ==
439 EXTERNAL_SHORT_ARRAY_TYPE;
440}
441
442
443bool Object::IsExternalUnsignedShortArray() {
444 return Object::IsHeapObject() &&
445 HeapObject::cast(this)->map()->instance_type() ==
446 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
447}
448
449
450bool Object::IsExternalIntArray() {
451 return Object::IsHeapObject() &&
452 HeapObject::cast(this)->map()->instance_type() ==
453 EXTERNAL_INT_ARRAY_TYPE;
454}
455
456
457bool Object::IsExternalUnsignedIntArray() {
458 return Object::IsHeapObject() &&
459 HeapObject::cast(this)->map()->instance_type() ==
460 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
461}
462
463
464bool Object::IsExternalFloatArray() {
465 return Object::IsHeapObject() &&
466 HeapObject::cast(this)->map()->instance_type() ==
467 EXTERNAL_FLOAT_ARRAY_TYPE;
468}
469
470
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000471bool Object::IsExternalDoubleArray() {
472 return Object::IsHeapObject() &&
473 HeapObject::cast(this)->map()->instance_type() ==
474 EXTERNAL_DOUBLE_ARRAY_TYPE;
475}
476
477
lrn@chromium.org303ada72010-10-27 09:33:13 +0000478bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000479 return HAS_FAILURE_TAG(this);
480}
481
482
lrn@chromium.org303ada72010-10-27 09:33:13 +0000483bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000484 return HAS_FAILURE_TAG(this)
485 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
486}
487
488
lrn@chromium.org303ada72010-10-27 09:33:13 +0000489bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000490 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000491 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000492}
493
494
lrn@chromium.org303ada72010-10-27 09:33:13 +0000495bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000496 return this == Failure::Exception();
497}
498
499
lrn@chromium.org303ada72010-10-27 09:33:13 +0000500bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000501 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000502}
503
504
505Failure* Failure::cast(MaybeObject* obj) {
506 ASSERT(HAS_FAILURE_TAG(obj));
507 return reinterpret_cast<Failure*>(obj);
508}
509
510
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000511bool Object::IsJSReceiver() {
512 return IsHeapObject() &&
513 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
514}
515
516
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000517bool Object::IsJSObject() {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000518 return IsJSReceiver() && !IsJSProxy();
519}
520
521
522bool Object::IsJSProxy() {
523 return Object::IsHeapObject() &&
524 (HeapObject::cast(this)->map()->instance_type() == JS_PROXY_TYPE ||
525 HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE);
526}
527
528
529bool Object::IsJSFunctionProxy() {
530 return Object::IsHeapObject() &&
531 HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000532}
533
534
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000535bool Object::IsJSWeakMap() {
536 return Object::IsJSObject() &&
537 HeapObject::cast(this)->map()->instance_type() == JS_WEAK_MAP_TYPE;
538}
539
540
ager@chromium.org32912102009-01-16 10:38:43 +0000541bool Object::IsJSContextExtensionObject() {
542 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000543 && (HeapObject::cast(this)->map()->instance_type() ==
544 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
ager@chromium.org32912102009-01-16 10:38:43 +0000545}
546
547
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000548bool Object::IsMap() {
549 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000550 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000551}
552
553
554bool Object::IsFixedArray() {
555 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000556 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000557}
558
559
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000560bool Object::IsFixedDoubleArray() {
561 return Object::IsHeapObject()
562 && HeapObject::cast(this)->map()->instance_type() ==
563 FIXED_DOUBLE_ARRAY_TYPE;
564}
565
566
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000567bool Object::IsDescriptorArray() {
568 return IsFixedArray();
569}
570
571
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000572bool Object::IsDeoptimizationInputData() {
573 // Must be a fixed array.
574 if (!IsFixedArray()) return false;
575
576 // There's no sure way to detect the difference between a fixed array and
577 // a deoptimization data array. Since this is used for asserts we can
578 // check that the length is zero or else the fixed size plus a multiple of
579 // the entry size.
580 int length = FixedArray::cast(this)->length();
581 if (length == 0) return true;
582
583 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
584 return length >= 0 &&
585 length % DeoptimizationInputData::kDeoptEntrySize == 0;
586}
587
588
589bool Object::IsDeoptimizationOutputData() {
590 if (!IsFixedArray()) return false;
591 // There's actually no way to see the difference between a fixed array and
592 // a deoptimization data array. Since this is used for asserts we can check
593 // that the length is plausible though.
594 if (FixedArray::cast(this)->length() % 2 != 0) return false;
595 return true;
596}
597
598
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000599bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000600 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000601 Map* map = HeapObject::cast(this)->map();
602 Heap* heap = map->GetHeap();
603 return (map == heap->function_context_map() ||
604 map == heap->catch_context_map() ||
605 map == heap->with_context_map() ||
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000606 map == heap->global_context_map() ||
607 map == heap->block_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000608 }
609 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000610}
611
612
613bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000614 return Object::IsHeapObject() &&
615 HeapObject::cast(this)->map() ==
616 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000617}
618
619
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000620bool Object::IsSerializedScopeInfo() {
621 return Object::IsHeapObject() &&
622 HeapObject::cast(this)->map() ==
623 HeapObject::cast(this)->GetHeap()->serialized_scope_info_map();
624}
625
626
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000627bool Object::IsJSFunction() {
628 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000629 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000630}
631
632
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000633template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000634 return obj->IsJSFunction();
635}
636
637
638bool Object::IsCode() {
639 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000640 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000641}
642
643
644bool Object::IsOddball() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000645 ASSERT(HEAP->is_safe_to_read_maps());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000646 return Object::IsHeapObject()
647 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
648}
649
650
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000651bool Object::IsJSGlobalPropertyCell() {
652 return Object::IsHeapObject()
653 && HeapObject::cast(this)->map()->instance_type()
654 == JS_GLOBAL_PROPERTY_CELL_TYPE;
655}
656
657
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000658bool Object::IsSharedFunctionInfo() {
659 return Object::IsHeapObject() &&
660 (HeapObject::cast(this)->map()->instance_type() ==
661 SHARED_FUNCTION_INFO_TYPE);
662}
663
664
665bool Object::IsJSValue() {
666 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000667 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
668}
669
670
671bool Object::IsJSMessageObject() {
672 return Object::IsHeapObject()
673 && (HeapObject::cast(this)->map()->instance_type() ==
674 JS_MESSAGE_OBJECT_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000675}
676
677
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000678bool Object::IsStringWrapper() {
679 return IsJSValue() && JSValue::cast(this)->value()->IsString();
680}
681
682
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000683bool Object::IsForeign() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000684 return Object::IsHeapObject()
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000685 && HeapObject::cast(this)->map()->instance_type() == FOREIGN_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000686}
687
688
689bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000690 return IsOddball() &&
691 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000692}
693
694
695bool Object::IsJSArray() {
696 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000697 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000698}
699
700
ager@chromium.org236ad962008-09-25 09:45:57 +0000701bool Object::IsJSRegExp() {
702 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000703 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
ager@chromium.org236ad962008-09-25 09:45:57 +0000704}
705
706
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000707template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000708 return obj->IsJSArray();
709}
710
711
712bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000713 return Object::IsHeapObject() &&
714 HeapObject::cast(this)->map() ==
715 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000716}
717
718
719bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000720 return IsHashTable() &&
721 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000722}
723
724
725bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000726 return IsHashTable() && this ==
727 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000728}
729
730
ager@chromium.orgac091b72010-05-05 07:34:42 +0000731bool Object::IsJSFunctionResultCache() {
732 if (!IsFixedArray()) return false;
733 FixedArray* self = FixedArray::cast(this);
734 int length = self->length();
735 if (length < JSFunctionResultCache::kEntriesIndex) return false;
736 if ((length - JSFunctionResultCache::kEntriesIndex)
737 % JSFunctionResultCache::kEntrySize != 0) {
738 return false;
739 }
740#ifdef DEBUG
741 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
742#endif
743 return true;
744}
745
746
ricow@chromium.org65fae842010-08-25 15:26:24 +0000747bool Object::IsNormalizedMapCache() {
748 if (!IsFixedArray()) return false;
749 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
750 return false;
751 }
752#ifdef DEBUG
753 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
754#endif
755 return true;
756}
757
758
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000759bool Object::IsCompilationCacheTable() {
760 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000761}
762
763
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000764bool Object::IsCodeCacheHashTable() {
765 return IsHashTable();
766}
767
768
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000769bool Object::IsPolymorphicCodeCacheHashTable() {
770 return IsHashTable();
771}
772
773
ager@chromium.org236ad962008-09-25 09:45:57 +0000774bool Object::IsMapCache() {
775 return IsHashTable();
776}
777
778
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000779bool Object::IsPrimitive() {
780 return IsOddball() || IsNumber() || IsString();
781}
782
783
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000784bool Object::IsJSGlobalProxy() {
785 bool result = IsHeapObject() &&
786 (HeapObject::cast(this)->map()->instance_type() ==
787 JS_GLOBAL_PROXY_TYPE);
788 ASSERT(!result || IsAccessCheckNeeded());
789 return result;
790}
791
792
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000793bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000794 if (!IsHeapObject()) return false;
795
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000796 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000797 return type == JS_GLOBAL_OBJECT_TYPE ||
798 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000799}
800
801
802bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000803 return IsHeapObject() &&
804 (HeapObject::cast(this)->map()->instance_type() ==
805 JS_GLOBAL_OBJECT_TYPE);
806}
807
808
809bool Object::IsJSBuiltinsObject() {
810 return IsHeapObject() &&
811 (HeapObject::cast(this)->map()->instance_type() ==
812 JS_BUILTINS_OBJECT_TYPE);
813}
814
815
816bool Object::IsUndetectableObject() {
817 return IsHeapObject()
818 && HeapObject::cast(this)->map()->is_undetectable();
819}
820
821
822bool Object::IsAccessCheckNeeded() {
823 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000824 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000825}
826
827
828bool Object::IsStruct() {
829 if (!IsHeapObject()) return false;
830 switch (HeapObject::cast(this)->map()->instance_type()) {
831#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
832 STRUCT_LIST(MAKE_STRUCT_CASE)
833#undef MAKE_STRUCT_CASE
834 default: return false;
835 }
836}
837
838
839#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
840 bool Object::Is##Name() { \
841 return Object::IsHeapObject() \
842 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
843 }
844 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
845#undef MAKE_STRUCT_PREDICATE
846
847
848bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000849 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000850}
851
852
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000853bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000854 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
855}
856
857
858bool Object::IsTheHole() {
859 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000860}
861
862
863bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000864 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000865}
866
867
868bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000869 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000870}
871
872
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000873bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000874 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000875}
876
877
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000878double Object::Number() {
879 ASSERT(IsNumber());
880 return IsSmi()
881 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
882 : reinterpret_cast<HeapNumber*>(this)->value();
883}
884
885
lrn@chromium.org303ada72010-10-27 09:33:13 +0000886MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000887 if (IsSmi()) return this;
888 if (IsHeapNumber()) {
889 double value = HeapNumber::cast(this)->value();
890 int int_value = FastD2I(value);
891 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
892 return Smi::FromInt(int_value);
893 }
894 }
895 return Failure::Exception();
896}
897
898
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000899bool Object::HasSpecificClassOf(String* name) {
900 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
901}
902
903
lrn@chromium.org303ada72010-10-27 09:33:13 +0000904MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000905 // GetElement can trigger a getter which can cause allocation.
906 // This was not always the case. This ASSERT is here to catch
907 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000908 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000909 return GetElementWithReceiver(this, index);
910}
911
912
lrn@chromium.org303ada72010-10-27 09:33:13 +0000913Object* Object::GetElementNoExceptionThrown(uint32_t index) {
914 MaybeObject* maybe = GetElementWithReceiver(this, index);
915 ASSERT(!maybe->IsFailure());
916 Object* result = NULL; // Initialization to please compiler.
917 maybe->ToObject(&result);
918 return result;
919}
920
921
922MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000923 PropertyAttributes attributes;
924 return GetPropertyWithReceiver(this, key, &attributes);
925}
926
927
lrn@chromium.org303ada72010-10-27 09:33:13 +0000928MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000929 return GetPropertyWithReceiver(this, key, attributes);
930}
931
932
933#define FIELD_ADDR(p, offset) \
934 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
935
936#define READ_FIELD(p, offset) \
937 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
938
939#define WRITE_FIELD(p, offset, value) \
940 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
941
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000942// TODO(isolates): Pass heap in to these macros.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000943#define WRITE_BARRIER(object, offset) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000944 object->GetHeap()->RecordWrite(object->address(), offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000945
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000946// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000947// write due to the assert validating the written value.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000948#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, mode) \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000949 if (mode == UPDATE_WRITE_BARRIER) { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000950 heap->RecordWrite(object->address(), offset); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000951 } else { \
952 ASSERT(mode == SKIP_WRITE_BARRIER); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000953 ASSERT(heap->InNewSpace(object) || \
954 !heap->InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000955 Page::FromAddress(object->address())-> \
956 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000957 }
958
lrn@chromium.org7516f052011-03-30 08:52:27 +0000959#ifndef V8_TARGET_ARCH_MIPS
960 #define READ_DOUBLE_FIELD(p, offset) \
961 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
962#else // V8_TARGET_ARCH_MIPS
963 // Prevent gcc from using load-double (mips ldc1) on (possibly)
964 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000965 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000966 union conversion {
967 double d;
968 uint32_t u[2];
969 } c;
970 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
971 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
972 return c.d;
973 }
974 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
975#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000976
lrn@chromium.org7516f052011-03-30 08:52:27 +0000977
978#ifndef V8_TARGET_ARCH_MIPS
979 #define WRITE_DOUBLE_FIELD(p, offset, value) \
980 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
981#else // V8_TARGET_ARCH_MIPS
982 // Prevent gcc from using store-double (mips sdc1) on (possibly)
983 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000984 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000985 double value) {
986 union conversion {
987 double d;
988 uint32_t u[2];
989 } c;
990 c.d = value;
991 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
992 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
993 }
994 #define WRITE_DOUBLE_FIELD(p, offset, value) \
995 write_double_field(p, offset, value)
996#endif // V8_TARGET_ARCH_MIPS
997
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000998
999#define READ_INT_FIELD(p, offset) \
1000 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
1001
1002#define WRITE_INT_FIELD(p, offset, value) \
1003 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
1004
ager@chromium.org3e875802009-06-29 08:26:34 +00001005#define READ_INTPTR_FIELD(p, offset) \
1006 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
1007
1008#define WRITE_INTPTR_FIELD(p, offset, value) \
1009 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
1010
ager@chromium.org7c537e22008-10-16 08:43:32 +00001011#define READ_UINT32_FIELD(p, offset) \
1012 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
1013
1014#define WRITE_UINT32_FIELD(p, offset, value) \
1015 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
1016
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001017#define READ_SHORT_FIELD(p, offset) \
1018 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
1019
1020#define WRITE_SHORT_FIELD(p, offset, value) \
1021 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
1022
1023#define READ_BYTE_FIELD(p, offset) \
1024 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
1025
1026#define WRITE_BYTE_FIELD(p, offset, value) \
1027 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
1028
1029
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +00001030Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
1031 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001032}
1033
1034
1035int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +00001036 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001037}
1038
1039
1040Smi* Smi::FromInt(int value) {
1041 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001042 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +00001043 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001044 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +00001045 return reinterpret_cast<Smi*>(tagged_value);
1046}
1047
1048
1049Smi* Smi::FromIntptr(intptr_t value) {
1050 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001051 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
1052 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001053}
1054
1055
1056Failure::Type Failure::type() const {
1057 return static_cast<Type>(value() & kFailureTypeTagMask);
1058}
1059
1060
1061bool Failure::IsInternalError() const {
1062 return type() == INTERNAL_ERROR;
1063}
1064
1065
1066bool Failure::IsOutOfMemoryException() const {
1067 return type() == OUT_OF_MEMORY_EXCEPTION;
1068}
1069
1070
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001071AllocationSpace Failure::allocation_space() const {
1072 ASSERT_EQ(RETRY_AFTER_GC, type());
1073 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1074 & kSpaceTagMask);
1075}
1076
1077
1078Failure* Failure::InternalError() {
1079 return Construct(INTERNAL_ERROR);
1080}
1081
1082
1083Failure* Failure::Exception() {
1084 return Construct(EXCEPTION);
1085}
1086
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001087
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001088Failure* Failure::OutOfMemoryException() {
1089 return Construct(OUT_OF_MEMORY_EXCEPTION);
1090}
1091
1092
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001093intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001094 return static_cast<intptr_t>(
1095 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001096}
1097
1098
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001099Failure* Failure::RetryAfterGC() {
1100 return RetryAfterGC(NEW_SPACE);
1101}
1102
1103
1104Failure* Failure::RetryAfterGC(AllocationSpace space) {
1105 ASSERT((space & ~kSpaceTagMask) == 0);
1106 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001107}
1108
1109
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001110Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001111 uintptr_t info =
1112 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001113 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001114 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001115}
1116
1117
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001118bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001119#ifdef DEBUG
1120 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1121#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001122
1123#ifdef V8_TARGET_ARCH_X64
1124 // To be representable as a long smi, the value must be a 32-bit integer.
1125 bool result = (value == static_cast<int32_t>(value));
1126#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001127 // To be representable as an tagged small integer, the two
1128 // most-significant bits of 'value' must be either 00 or 11 due to
1129 // sign-extension. To check this we add 01 to the two
1130 // most-significant bits, and check if the most-significant bit is 0
1131 //
1132 // CAUTION: The original code below:
1133 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1134 // may lead to incorrect results according to the C language spec, and
1135 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1136 // compiler may produce undefined results in case of signed integer
1137 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001138 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001139#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001140 ASSERT(result == in_range);
1141 return result;
1142}
1143
1144
kasper.lund7276f142008-07-30 08:49:36 +00001145MapWord MapWord::FromMap(Map* map) {
1146 return MapWord(reinterpret_cast<uintptr_t>(map));
1147}
1148
1149
1150Map* MapWord::ToMap() {
1151 return reinterpret_cast<Map*>(value_);
1152}
1153
1154
1155bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001156 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001157}
1158
1159
1160MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001161 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1162 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001163}
1164
1165
1166HeapObject* MapWord::ToForwardingAddress() {
1167 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001168 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001169}
1170
1171
1172bool MapWord::IsMarked() {
1173 return (value_ & kMarkingMask) == 0;
1174}
1175
1176
1177void MapWord::SetMark() {
1178 value_ &= ~kMarkingMask;
1179}
1180
1181
1182void MapWord::ClearMark() {
1183 value_ |= kMarkingMask;
1184}
1185
1186
1187bool MapWord::IsOverflowed() {
1188 return (value_ & kOverflowMask) != 0;
1189}
1190
1191
1192void MapWord::SetOverflow() {
1193 value_ |= kOverflowMask;
1194}
1195
1196
1197void MapWord::ClearOverflow() {
1198 value_ &= ~kOverflowMask;
1199}
1200
1201
1202MapWord MapWord::EncodeAddress(Address map_address, int offset) {
1203 // Offset is the distance in live bytes from the first live object in the
1204 // same page. The offset between two objects in the same page should not
1205 // exceed the object area size of a page.
1206 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1207
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001208 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001209 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1210
1211 Page* map_page = Page::FromAddress(map_address);
1212 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1213
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001214 uintptr_t map_page_offset =
1215 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001216
1217 uintptr_t encoding =
1218 (compact_offset << kForwardingOffsetShift) |
1219 (map_page_offset << kMapPageOffsetShift) |
1220 (map_page->mc_page_index << kMapPageIndexShift);
1221 return MapWord(encoding);
1222}
1223
1224
1225Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001226 int map_page_index =
1227 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001228 ASSERT_MAP_PAGE_INDEX(map_page_index);
1229
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001230 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001231 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1232 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001233
1234 return (map_space->PageAddress(map_page_index) + map_page_offset);
1235}
1236
1237
1238int MapWord::DecodeOffset() {
1239 // The offset field is represented in the kForwardingOffsetBits
1240 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001241 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1242 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1243 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001244}
1245
1246
1247MapWord MapWord::FromEncodedAddress(Address address) {
1248 return MapWord(reinterpret_cast<uintptr_t>(address));
1249}
1250
1251
1252Address MapWord::ToEncodedAddress() {
1253 return reinterpret_cast<Address>(value_);
1254}
1255
1256
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001257#ifdef DEBUG
1258void HeapObject::VerifyObjectField(int offset) {
1259 VerifyPointer(READ_FIELD(this, offset));
1260}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001261
1262void HeapObject::VerifySmiField(int offset) {
1263 ASSERT(READ_FIELD(this, offset)->IsSmi());
1264}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001265#endif
1266
1267
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001268Heap* HeapObject::GetHeap() {
1269 // During GC, the map pointer in HeapObject is used in various ways that
1270 // prevent us from retrieving Heap from the map.
1271 // Assert that we are not in GC, implement GC code in a way that it doesn't
1272 // pull heap from the map.
1273 ASSERT(HEAP->is_safe_to_read_maps());
1274 return map()->heap();
1275}
1276
1277
1278Isolate* HeapObject::GetIsolate() {
1279 return GetHeap()->isolate();
1280}
1281
1282
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001283Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001284 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001285}
1286
1287
1288void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001289 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001290}
1291
1292
kasper.lund7276f142008-07-30 08:49:36 +00001293MapWord HeapObject::map_word() {
1294 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1295}
1296
1297
1298void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001299 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001300 // here.
1301 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1302}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001303
1304
1305HeapObject* HeapObject::FromAddress(Address address) {
1306 ASSERT_TAG_ALIGNED(address);
1307 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1308}
1309
1310
1311Address HeapObject::address() {
1312 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1313}
1314
1315
1316int HeapObject::Size() {
1317 return SizeFromMap(map());
1318}
1319
1320
1321void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1322 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1323 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1324}
1325
1326
1327void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1328 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1329}
1330
1331
kasper.lund7276f142008-07-30 08:49:36 +00001332bool HeapObject::IsMarked() {
1333 return map_word().IsMarked();
1334}
1335
1336
1337void HeapObject::SetMark() {
1338 ASSERT(!IsMarked());
1339 MapWord first_word = map_word();
1340 first_word.SetMark();
1341 set_map_word(first_word);
1342}
1343
1344
1345void HeapObject::ClearMark() {
1346 ASSERT(IsMarked());
1347 MapWord first_word = map_word();
1348 first_word.ClearMark();
1349 set_map_word(first_word);
1350}
1351
1352
1353bool HeapObject::IsOverflowed() {
1354 return map_word().IsOverflowed();
1355}
1356
1357
1358void HeapObject::SetOverflow() {
1359 MapWord first_word = map_word();
1360 first_word.SetOverflow();
1361 set_map_word(first_word);
1362}
1363
1364
1365void HeapObject::ClearOverflow() {
1366 ASSERT(IsOverflowed());
1367 MapWord first_word = map_word();
1368 first_word.ClearOverflow();
1369 set_map_word(first_word);
1370}
1371
1372
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001373double HeapNumber::value() {
1374 return READ_DOUBLE_FIELD(this, kValueOffset);
1375}
1376
1377
1378void HeapNumber::set_value(double value) {
1379 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1380}
1381
1382
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001383int HeapNumber::get_exponent() {
1384 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1385 kExponentShift) - kExponentBias;
1386}
1387
1388
1389int HeapNumber::get_sign() {
1390 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1391}
1392
1393
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001394ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001395
1396
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001397FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001398 Object* array = READ_FIELD(this, kElementsOffset);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001399 ASSERT(array->HasValidElements());
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001400 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001401}
1402
1403
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001404void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001405 ASSERT(map()->has_fast_elements() ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001406 (value->map() == GetHeap()->fixed_array_map() ||
1407 value->map() == GetHeap()->fixed_cow_array_map()));
lrn@chromium.orgd4e9e222011-08-03 12:01:58 +00001408 ASSERT(map()->has_fast_double_elements() ==
1409 value->IsFixedDoubleArray());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001410 ASSERT(value->HasValidElements());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001411 WRITE_FIELD(this, kElementsOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001412 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001413}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001414
1415
1416void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001417 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1418 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001419}
1420
1421
1422void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001423 ASSERT(map()->has_fast_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001424 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1425 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001426}
1427
1428
lrn@chromium.org303ada72010-10-27 09:33:13 +00001429MaybeObject* JSObject::ResetElements() {
1430 Object* obj;
1431 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
1432 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1433 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001434 set_map(Map::cast(obj));
1435 initialize_elements();
1436 return this;
1437}
1438
1439
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001440ACCESSORS(Oddball, to_string, String, kToStringOffset)
1441ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1442
1443
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001444byte Oddball::kind() {
1445 return READ_BYTE_FIELD(this, kKindOffset);
1446}
1447
1448
1449void Oddball::set_kind(byte value) {
1450 WRITE_BYTE_FIELD(this, kKindOffset, value);
1451}
1452
1453
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001454Object* JSGlobalPropertyCell::value() {
1455 return READ_FIELD(this, kValueOffset);
1456}
1457
1458
1459void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1460 // The write barrier is not used for global property cells.
1461 ASSERT(!val->IsJSGlobalPropertyCell());
1462 WRITE_FIELD(this, kValueOffset, val);
1463}
1464
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001465
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001466int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001467 InstanceType type = map()->instance_type();
1468 // Check for the most common kind of JavaScript object before
1469 // falling into the generic switch. This speeds up the internal
1470 // field operations considerably on average.
1471 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1472 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001473 case JS_GLOBAL_PROXY_TYPE:
1474 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001475 case JS_GLOBAL_OBJECT_TYPE:
1476 return JSGlobalObject::kSize;
1477 case JS_BUILTINS_OBJECT_TYPE:
1478 return JSBuiltinsObject::kSize;
1479 case JS_FUNCTION_TYPE:
1480 return JSFunction::kSize;
1481 case JS_VALUE_TYPE:
1482 return JSValue::kSize;
1483 case JS_ARRAY_TYPE:
1484 return JSValue::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001485 case JS_WEAK_MAP_TYPE:
1486 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001487 case JS_REGEXP_TYPE:
1488 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001489 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001490 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001491 case JS_MESSAGE_OBJECT_TYPE:
1492 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001493 default:
1494 UNREACHABLE();
1495 return 0;
1496 }
1497}
1498
1499
1500int JSObject::GetInternalFieldCount() {
1501 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001502 // Make sure to adjust for the number of in-object properties. These
1503 // properties do contribute to the size, but are not internal fields.
1504 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1505 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001506}
1507
1508
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001509int JSObject::GetInternalFieldOffset(int index) {
1510 ASSERT(index < GetInternalFieldCount() && index >= 0);
1511 return GetHeaderSize() + (kPointerSize * index);
1512}
1513
1514
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001515Object* JSObject::GetInternalField(int index) {
1516 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001517 // Internal objects do follow immediately after the header, whereas in-object
1518 // properties are at the end of the object. Therefore there is no need
1519 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001520 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1521}
1522
1523
1524void JSObject::SetInternalField(int index, Object* value) {
1525 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001526 // Internal objects do follow immediately after the header, whereas in-object
1527 // properties are at the end of the object. Therefore there is no need
1528 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001529 int offset = GetHeaderSize() + (kPointerSize * index);
1530 WRITE_FIELD(this, offset, value);
1531 WRITE_BARRIER(this, offset);
1532}
1533
1534
ager@chromium.org7c537e22008-10-16 08:43:32 +00001535// Access fast-case object properties at index. The use of these routines
1536// is needed to correctly distinguish between properties stored in-object and
1537// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001538Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001539 // Adjust for the number of properties stored in the object.
1540 index -= map()->inobject_properties();
1541 if (index < 0) {
1542 int offset = map()->instance_size() + (index * kPointerSize);
1543 return READ_FIELD(this, offset);
1544 } else {
1545 ASSERT(index < properties()->length());
1546 return properties()->get(index);
1547 }
1548}
1549
1550
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001551Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001552 // Adjust for the number of properties stored in the object.
1553 index -= map()->inobject_properties();
1554 if (index < 0) {
1555 int offset = map()->instance_size() + (index * kPointerSize);
1556 WRITE_FIELD(this, offset, value);
1557 WRITE_BARRIER(this, offset);
1558 } else {
1559 ASSERT(index < properties()->length());
1560 properties()->set(index, value);
1561 }
1562 return value;
1563}
1564
1565
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001566int JSObject::GetInObjectPropertyOffset(int index) {
1567 // Adjust for the number of properties stored in the object.
1568 index -= map()->inobject_properties();
1569 ASSERT(index < 0);
1570 return map()->instance_size() + (index * kPointerSize);
1571}
1572
1573
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001574Object* JSObject::InObjectPropertyAt(int index) {
1575 // Adjust for the number of properties stored in the object.
1576 index -= map()->inobject_properties();
1577 ASSERT(index < 0);
1578 int offset = map()->instance_size() + (index * kPointerSize);
1579 return READ_FIELD(this, offset);
1580}
1581
1582
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001583Object* JSObject::InObjectPropertyAtPut(int index,
1584 Object* value,
1585 WriteBarrierMode mode) {
1586 // Adjust for the number of properties stored in the object.
1587 index -= map()->inobject_properties();
1588 ASSERT(index < 0);
1589 int offset = map()->instance_size() + (index * kPointerSize);
1590 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001591 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001592 return value;
1593}
1594
1595
1596
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001597void JSObject::InitializeBody(int object_size, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001598 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001599 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001600 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001601 }
1602}
1603
1604
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001605bool JSObject::HasFastProperties() {
1606 return !properties()->IsDictionary();
1607}
1608
1609
1610int JSObject::MaxFastProperties() {
1611 // Allow extra fast properties if the object has more than
1612 // kMaxFastProperties in-object properties. When this is the case,
1613 // it is very unlikely that the object is being used as a dictionary
1614 // and there is a good chance that allowing more map transitions
1615 // will be worth it.
1616 return Max(map()->inobject_properties(), kMaxFastProperties);
1617}
1618
1619
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001620void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001621 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001622 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001623 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001624 }
1625}
1626
1627
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001628bool Object::ToArrayIndex(uint32_t* index) {
1629 if (IsSmi()) {
1630 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001631 if (value < 0) return false;
1632 *index = value;
1633 return true;
1634 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001635 if (IsHeapNumber()) {
1636 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001637 uint32_t uint_value = static_cast<uint32_t>(value);
1638 if (value == static_cast<double>(uint_value)) {
1639 *index = uint_value;
1640 return true;
1641 }
1642 }
1643 return false;
1644}
1645
1646
1647bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1648 if (!this->IsJSValue()) return false;
1649
1650 JSValue* js_value = JSValue::cast(this);
1651 if (!js_value->value()->IsString()) return false;
1652
1653 String* str = String::cast(js_value->value());
1654 if (index >= (uint32_t)str->length()) return false;
1655
1656 return true;
1657}
1658
1659
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001660FixedArrayBase* FixedArrayBase::cast(Object* object) {
1661 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1662 return reinterpret_cast<FixedArrayBase*>(object);
1663}
1664
1665
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001666Object* FixedArray::get(int index) {
1667 ASSERT(index >= 0 && index < this->length());
1668 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1669}
1670
1671
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001672void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001673 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001674 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001675 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1676 int offset = kHeaderSize + index * kPointerSize;
1677 WRITE_FIELD(this, offset, value);
1678}
1679
1680
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001681void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001682 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001683 ASSERT(index >= 0 && index < this->length());
1684 int offset = kHeaderSize + index * kPointerSize;
1685 WRITE_FIELD(this, offset, value);
1686 WRITE_BARRIER(this, offset);
1687}
1688
1689
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001690inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1691 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1692}
1693
1694
1695inline double FixedDoubleArray::hole_nan_as_double() {
1696 return BitCast<double, uint64_t>(kHoleNanInt64);
1697}
1698
1699
1700inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1701 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1702 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1703 return OS::nan_value();
1704}
1705
1706
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001707double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001708 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1709 map() != HEAP->fixed_array_map());
1710 ASSERT(index >= 0 && index < this->length());
1711 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1712 ASSERT(!is_the_hole_nan(result));
1713 return result;
1714}
1715
1716
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001717MaybeObject* FixedDoubleArray::get(int index) {
1718 if (is_the_hole(index)) {
1719 return GetHeap()->the_hole_value();
1720 } else {
1721 return GetHeap()->NumberFromDouble(get_scalar(index));
1722 }
1723}
1724
1725
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001726void FixedDoubleArray::set(int index, double value) {
1727 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1728 map() != HEAP->fixed_array_map());
1729 int offset = kHeaderSize + index * kDoubleSize;
1730 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1731 WRITE_DOUBLE_FIELD(this, offset, value);
1732}
1733
1734
1735void FixedDoubleArray::set_the_hole(int index) {
1736 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1737 map() != HEAP->fixed_array_map());
1738 int offset = kHeaderSize + index * kDoubleSize;
1739 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1740}
1741
1742
1743bool FixedDoubleArray::is_the_hole(int index) {
1744 int offset = kHeaderSize + index * kDoubleSize;
1745 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1746}
1747
1748
1749void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1750 int old_length = from->length();
1751 ASSERT(old_length < length());
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001752 if (old_length * kDoubleSize >= OS::kMinComplexMemCopy) {
1753 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1754 FIELD_ADDR(from, kHeaderSize),
1755 old_length * kDoubleSize);
1756 } else {
1757 for (int i = 0; i < old_length; ++i) {
1758 set(i, from->get_scalar(i));
1759 }
1760 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001761 int offset = kHeaderSize + old_length * kDoubleSize;
1762 for (int current = from->length(); current < length(); ++current) {
1763 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1764 offset += kDoubleSize;
1765 }
1766}
1767
1768
1769void FixedDoubleArray::Initialize(FixedArray* from) {
1770 int old_length = from->length();
1771 ASSERT(old_length < length());
1772 for (int i = 0; i < old_length; i++) {
1773 Object* hole_or_object = from->get(i);
1774 if (hole_or_object->IsTheHole()) {
1775 set_the_hole(i);
1776 } else {
1777 set(i, hole_or_object->Number());
1778 }
1779 }
1780 int offset = kHeaderSize + old_length * kDoubleSize;
1781 for (int current = from->length(); current < length(); ++current) {
1782 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1783 offset += kDoubleSize;
1784 }
1785}
1786
1787
1788void FixedDoubleArray::Initialize(NumberDictionary* from) {
1789 int offset = kHeaderSize;
1790 for (int current = 0; current < length(); ++current) {
1791 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1792 offset += kDoubleSize;
1793 }
1794 for (int i = 0; i < from->Capacity(); i++) {
1795 Object* key = from->KeyAt(i);
1796 if (key->IsNumber()) {
1797 uint32_t entry = static_cast<uint32_t>(key->Number());
1798 set(entry, from->ValueAt(i)->Number());
1799 }
1800 }
1801}
1802
1803
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001804WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001805 if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001806 return UPDATE_WRITE_BARRIER;
1807}
1808
1809
1810void FixedArray::set(int index,
1811 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001812 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001813 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001814 ASSERT(index >= 0 && index < this->length());
1815 int offset = kHeaderSize + index * kPointerSize;
1816 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001817 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001818}
1819
1820
1821void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001822 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001823 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001824 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001825 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1826}
1827
1828
1829void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001830 ASSERT(map() != HEAP->fixed_cow_array_map());
1831 set_undefined(GetHeap(), index);
1832}
1833
1834
1835void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001836 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001837 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001838 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001839 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001840}
1841
1842
ager@chromium.org236ad962008-09-25 09:45:57 +00001843void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001844 set_null(GetHeap(), index);
1845}
1846
1847
1848void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001849 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001850 ASSERT(!heap->InNewSpace(heap->null_value()));
1851 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001852}
1853
1854
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001855void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001856 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001857 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001858 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1859 WRITE_FIELD(this,
1860 kHeaderSize + index * kPointerSize,
1861 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001862}
1863
1864
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001865void FixedArray::set_unchecked(int index, Smi* value) {
1866 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1867 int offset = kHeaderSize + index * kPointerSize;
1868 WRITE_FIELD(this, offset, value);
1869}
1870
1871
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001872void FixedArray::set_unchecked(Heap* heap,
1873 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001874 Object* value,
1875 WriteBarrierMode mode) {
1876 int offset = kHeaderSize + index * kPointerSize;
1877 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001878 CONDITIONAL_WRITE_BARRIER(heap, this, offset, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001879}
1880
1881
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001882void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001883 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001884 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1885 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001886}
1887
1888
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001889Object** FixedArray::data_start() {
1890 return HeapObject::RawField(this, kHeaderSize);
1891}
1892
1893
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001894bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001895 ASSERT(this->IsSmi() ||
1896 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001897 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001898 return this->IsSmi() || length() <= kFirstIndex;
1899}
1900
1901
1902int DescriptorArray::bit_field3_storage() {
1903 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1904 return Smi::cast(storage)->value();
1905}
1906
1907void DescriptorArray::set_bit_field3_storage(int value) {
1908 ASSERT(!IsEmpty());
1909 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001910}
1911
1912
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001913void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1914 Object* tmp = array->get(first);
1915 fast_set(array, first, array->get(second));
1916 fast_set(array, second, tmp);
1917}
1918
1919
1920int DescriptorArray::Search(String* name) {
1921 SLOW_ASSERT(IsSortedNoDuplicates());
1922
1923 // Check for empty descriptor array.
1924 int nof = number_of_descriptors();
1925 if (nof == 0) return kNotFound;
1926
1927 // Fast case: do linear search for small arrays.
1928 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001929 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001930 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001931 }
1932
1933 // Slow case: perform binary search.
1934 return BinarySearch(name, 0, nof - 1);
1935}
1936
1937
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001938int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001939 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001940 if (number == DescriptorLookupCache::kAbsent) {
1941 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001942 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001943 }
1944 return number;
1945}
1946
1947
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001948String* DescriptorArray::GetKey(int descriptor_number) {
1949 ASSERT(descriptor_number < number_of_descriptors());
1950 return String::cast(get(ToKeyIndex(descriptor_number)));
1951}
1952
1953
1954Object* DescriptorArray::GetValue(int descriptor_number) {
1955 ASSERT(descriptor_number < number_of_descriptors());
1956 return GetContentArray()->get(ToValueIndex(descriptor_number));
1957}
1958
1959
1960Smi* DescriptorArray::GetDetails(int descriptor_number) {
1961 ASSERT(descriptor_number < number_of_descriptors());
1962 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1963}
1964
1965
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001966PropertyType DescriptorArray::GetType(int descriptor_number) {
1967 ASSERT(descriptor_number < number_of_descriptors());
1968 return PropertyDetails(GetDetails(descriptor_number)).type();
1969}
1970
1971
1972int DescriptorArray::GetFieldIndex(int descriptor_number) {
1973 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1974}
1975
1976
1977JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1978 return JSFunction::cast(GetValue(descriptor_number));
1979}
1980
1981
1982Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1983 ASSERT(GetType(descriptor_number) == CALLBACKS);
1984 return GetValue(descriptor_number);
1985}
1986
1987
1988AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1989 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001990 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
1991 return reinterpret_cast<AccessorDescriptor*>(p->address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001992}
1993
1994
1995bool DescriptorArray::IsProperty(int descriptor_number) {
1996 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1997}
1998
1999
2000bool DescriptorArray::IsTransition(int descriptor_number) {
2001 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002002 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002003 t == ELEMENTS_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002004}
2005
2006
2007bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
2008 return GetType(descriptor_number) == NULL_DESCRIPTOR;
2009}
2010
2011
2012bool DescriptorArray::IsDontEnum(int descriptor_number) {
2013 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
2014}
2015
2016
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002017void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2018 desc->Init(GetKey(descriptor_number),
2019 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002020 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002021}
2022
2023
2024void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
2025 // Range check.
2026 ASSERT(descriptor_number < number_of_descriptors());
2027
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00002028 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002029 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
2030 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002031
2032 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
2033 FixedArray* content_array = GetContentArray();
2034 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
2035 fast_set(content_array, ToDetailsIndex(descriptor_number),
2036 desc->GetDetails().AsSmi());
2037}
2038
2039
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002040void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
2041 Descriptor desc;
2042 src->Get(src_index, &desc);
2043 Set(index, &desc);
2044}
2045
2046
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002047void DescriptorArray::Swap(int first, int second) {
2048 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
2049 FixedArray* content_array = GetContentArray();
2050 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
2051 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
2052}
2053
2054
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002055template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002056int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2057 const int kMinCapacity = 32;
2058 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2059 if (capacity < kMinCapacity) {
2060 capacity = kMinCapacity; // Guarantee min capacity.
2061 }
2062 return capacity;
2063}
2064
2065
2066template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002067int HashTable<Shape, Key>::FindEntry(Key key) {
2068 return FindEntry(GetIsolate(), key);
2069}
2070
2071
2072// Find entry for key otherwise return kNotFound.
2073template<typename Shape, typename Key>
2074int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2075 uint32_t capacity = Capacity();
2076 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
2077 uint32_t count = 1;
2078 // EnsureCapacity will guarantee the hash table is never full.
2079 while (true) {
2080 Object* element = KeyAt(entry);
2081 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
2082 if (element != isolate->heap()->null_value() &&
2083 Shape::IsMatch(key, element)) return entry;
2084 entry = NextProbe(entry, count++, capacity);
2085 }
2086 return kNotFound;
2087}
2088
2089
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002090bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002091 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002092 if (!max_index_object->IsSmi()) return false;
2093 return 0 !=
2094 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2095}
2096
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002097uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002098 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002099 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002100 if (!max_index_object->IsSmi()) return 0;
2101 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2102 return value >> kRequiresSlowElementsTagSize;
2103}
2104
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002105void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002106 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002107}
2108
2109
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002110// ------------------------------------
2111// Cast operations
2112
2113
2114CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002115CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002116CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002117CAST_ACCESSOR(DeoptimizationInputData)
2118CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002119CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002120CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002121CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002122CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002123CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002124CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002125CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002126CAST_ACCESSOR(String)
2127CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002128CAST_ACCESSOR(SeqAsciiString)
2129CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002130CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002131CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002132CAST_ACCESSOR(ExternalString)
2133CAST_ACCESSOR(ExternalAsciiString)
2134CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002135CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002136CAST_ACCESSOR(JSObject)
2137CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002138CAST_ACCESSOR(HeapObject)
2139CAST_ACCESSOR(HeapNumber)
2140CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002141CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002142CAST_ACCESSOR(SharedFunctionInfo)
2143CAST_ACCESSOR(Map)
2144CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002145CAST_ACCESSOR(GlobalObject)
2146CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002147CAST_ACCESSOR(JSGlobalObject)
2148CAST_ACCESSOR(JSBuiltinsObject)
2149CAST_ACCESSOR(Code)
2150CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002151CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002152CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002153CAST_ACCESSOR(JSFunctionProxy)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002154CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002155CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002156CAST_ACCESSOR(ByteArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00002157CAST_ACCESSOR(ExternalArray)
2158CAST_ACCESSOR(ExternalByteArray)
2159CAST_ACCESSOR(ExternalUnsignedByteArray)
2160CAST_ACCESSOR(ExternalShortArray)
2161CAST_ACCESSOR(ExternalUnsignedShortArray)
2162CAST_ACCESSOR(ExternalIntArray)
2163CAST_ACCESSOR(ExternalUnsignedIntArray)
2164CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002165CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002166CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002167CAST_ACCESSOR(Struct)
2168
2169
2170#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2171 STRUCT_LIST(MAKE_STRUCT_CAST)
2172#undef MAKE_STRUCT_CAST
2173
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002174
2175template <typename Shape, typename Key>
2176HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002177 ASSERT(obj->IsHashTable());
2178 return reinterpret_cast<HashTable*>(obj);
2179}
2180
2181
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002182SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002183
ager@chromium.orgac091b72010-05-05 07:34:42 +00002184SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002185
2186
2187uint32_t String::hash_field() {
2188 return READ_UINT32_FIELD(this, kHashFieldOffset);
2189}
2190
2191
2192void String::set_hash_field(uint32_t value) {
2193 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002194#if V8_HOST_ARCH_64_BIT
2195 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2196#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002197}
2198
2199
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002200bool String::Equals(String* other) {
2201 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002202 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2203 return false;
2204 }
2205 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002206}
2207
2208
lrn@chromium.org303ada72010-10-27 09:33:13 +00002209MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002210 if (!StringShape(this).IsCons()) return this;
2211 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002212 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002213 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002214}
2215
2216
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002217String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002218 MaybeObject* flat = TryFlatten(pretenure);
2219 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002220 if (!flat->ToObject(&successfully_flattened)) return this;
2221 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002222}
2223
2224
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002225uint16_t String::Get(int index) {
2226 ASSERT(index >= 0 && index < length());
2227 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002228 case kSeqStringTag | kAsciiStringTag:
2229 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2230 case kSeqStringTag | kTwoByteStringTag:
2231 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2232 case kConsStringTag | kAsciiStringTag:
2233 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002234 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002235 case kExternalStringTag | kAsciiStringTag:
2236 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2237 case kExternalStringTag | kTwoByteStringTag:
2238 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002239 case kSlicedStringTag | kAsciiStringTag:
2240 case kSlicedStringTag | kTwoByteStringTag:
2241 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002242 default:
2243 break;
2244 }
2245
2246 UNREACHABLE();
2247 return 0;
2248}
2249
2250
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002251void String::Set(int index, uint16_t value) {
2252 ASSERT(index >= 0 && index < length());
2253 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002254
ager@chromium.org5ec48922009-05-05 07:25:34 +00002255 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002256 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2257 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002258}
2259
2260
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002261bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002262 if (!StringShape(this).IsCons()) return true;
2263 return ConsString::cast(this)->second()->length() == 0;
2264}
2265
2266
2267String* String::GetUnderlying() {
2268 // Giving direct access to underlying string only makes sense if the
2269 // wrapping string is already flattened.
2270 ASSERT(this->IsFlat());
2271 ASSERT(StringShape(this).IsIndirect());
2272 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2273 const int kUnderlyingOffset = SlicedString::kParentOffset;
2274 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002275}
2276
2277
ager@chromium.org7c537e22008-10-16 08:43:32 +00002278uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002279 ASSERT(index >= 0 && index < length());
2280 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2281}
2282
2283
ager@chromium.org7c537e22008-10-16 08:43:32 +00002284void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002285 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2286 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2287 static_cast<byte>(value));
2288}
2289
2290
ager@chromium.org7c537e22008-10-16 08:43:32 +00002291Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002292 return FIELD_ADDR(this, kHeaderSize);
2293}
2294
2295
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002296char* SeqAsciiString::GetChars() {
2297 return reinterpret_cast<char*>(GetCharsAddress());
2298}
2299
2300
ager@chromium.org7c537e22008-10-16 08:43:32 +00002301Address SeqTwoByteString::GetCharsAddress() {
2302 return FIELD_ADDR(this, kHeaderSize);
2303}
2304
2305
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002306uc16* SeqTwoByteString::GetChars() {
2307 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2308}
2309
2310
ager@chromium.org7c537e22008-10-16 08:43:32 +00002311uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002312 ASSERT(index >= 0 && index < length());
2313 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2314}
2315
2316
ager@chromium.org7c537e22008-10-16 08:43:32 +00002317void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002318 ASSERT(index >= 0 && index < length());
2319 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2320}
2321
2322
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002323int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002324 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002325}
2326
2327
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002328int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002329 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002330}
2331
2332
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002333String* SlicedString::parent() {
2334 return String::cast(READ_FIELD(this, kParentOffset));
2335}
2336
2337
2338void SlicedString::set_parent(String* parent) {
2339 ASSERT(parent->IsSeqString());
2340 WRITE_FIELD(this, kParentOffset, parent);
2341}
2342
2343
2344SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2345
2346
ager@chromium.org870a0b62008-11-04 11:43:05 +00002347String* ConsString::first() {
2348 return String::cast(READ_FIELD(this, kFirstOffset));
2349}
2350
2351
2352Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002353 return READ_FIELD(this, kFirstOffset);
2354}
2355
2356
ager@chromium.org870a0b62008-11-04 11:43:05 +00002357void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002358 WRITE_FIELD(this, kFirstOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002359 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002360}
2361
2362
ager@chromium.org870a0b62008-11-04 11:43:05 +00002363String* ConsString::second() {
2364 return String::cast(READ_FIELD(this, kSecondOffset));
2365}
2366
2367
2368Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002369 return READ_FIELD(this, kSecondOffset);
2370}
2371
2372
ager@chromium.org870a0b62008-11-04 11:43:05 +00002373void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002374 WRITE_FIELD(this, kSecondOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002375 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002376}
2377
2378
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002379ExternalAsciiString::Resource* ExternalAsciiString::resource() {
2380 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2381}
2382
2383
2384void ExternalAsciiString::set_resource(
2385 ExternalAsciiString::Resource* resource) {
2386 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2387}
2388
2389
2390ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
2391 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2392}
2393
2394
2395void ExternalTwoByteString::set_resource(
2396 ExternalTwoByteString::Resource* resource) {
2397 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2398}
2399
2400
ager@chromium.orgac091b72010-05-05 07:34:42 +00002401void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002402 set_finger_index(kEntriesIndex);
2403 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002404}
2405
2406
2407void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002408 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002409 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002410 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002411 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002412 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002413 MakeZeroSize();
2414}
2415
2416
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002417int JSFunctionResultCache::size() {
2418 return Smi::cast(get(kCacheSizeIndex))->value();
2419}
2420
2421
2422void JSFunctionResultCache::set_size(int size) {
2423 set(kCacheSizeIndex, Smi::FromInt(size));
2424}
2425
2426
2427int JSFunctionResultCache::finger_index() {
2428 return Smi::cast(get(kFingerIndex))->value();
2429}
2430
2431
2432void JSFunctionResultCache::set_finger_index(int finger_index) {
2433 set(kFingerIndex, Smi::FromInt(finger_index));
2434}
2435
2436
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002437byte ByteArray::get(int index) {
2438 ASSERT(index >= 0 && index < this->length());
2439 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2440}
2441
2442
2443void ByteArray::set(int index, byte value) {
2444 ASSERT(index >= 0 && index < this->length());
2445 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2446}
2447
2448
2449int ByteArray::get_int(int index) {
2450 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2451 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2452}
2453
2454
2455ByteArray* ByteArray::FromDataStartAddress(Address address) {
2456 ASSERT_TAG_ALIGNED(address);
2457 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2458}
2459
2460
2461Address ByteArray::GetDataStartAddress() {
2462 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2463}
2464
2465
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002466uint8_t* ExternalPixelArray::external_pixel_pointer() {
2467 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002468}
2469
2470
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002471uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002472 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002473 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002474 return ptr[index];
2475}
2476
2477
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002478MaybeObject* ExternalPixelArray::get(int index) {
2479 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2480}
2481
2482
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002483void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002484 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002485 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002486 ptr[index] = value;
2487}
2488
2489
ager@chromium.org3811b432009-10-28 14:53:37 +00002490void* ExternalArray::external_pointer() {
2491 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2492 return reinterpret_cast<void*>(ptr);
2493}
2494
2495
2496void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2497 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2498 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2499}
2500
2501
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002502int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002503 ASSERT((index >= 0) && (index < this->length()));
2504 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2505 return ptr[index];
2506}
2507
2508
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002509MaybeObject* ExternalByteArray::get(int index) {
2510 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2511}
2512
2513
ager@chromium.org3811b432009-10-28 14:53:37 +00002514void ExternalByteArray::set(int index, int8_t value) {
2515 ASSERT((index >= 0) && (index < this->length()));
2516 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2517 ptr[index] = value;
2518}
2519
2520
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002521uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002522 ASSERT((index >= 0) && (index < this->length()));
2523 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2524 return ptr[index];
2525}
2526
2527
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002528MaybeObject* ExternalUnsignedByteArray::get(int index) {
2529 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2530}
2531
2532
ager@chromium.org3811b432009-10-28 14:53:37 +00002533void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2534 ASSERT((index >= 0) && (index < this->length()));
2535 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2536 ptr[index] = value;
2537}
2538
2539
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002540int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002541 ASSERT((index >= 0) && (index < this->length()));
2542 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2543 return ptr[index];
2544}
2545
2546
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002547MaybeObject* ExternalShortArray::get(int index) {
2548 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2549}
2550
2551
ager@chromium.org3811b432009-10-28 14:53:37 +00002552void ExternalShortArray::set(int index, int16_t value) {
2553 ASSERT((index >= 0) && (index < this->length()));
2554 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2555 ptr[index] = value;
2556}
2557
2558
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002559uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002560 ASSERT((index >= 0) && (index < this->length()));
2561 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2562 return ptr[index];
2563}
2564
2565
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002566MaybeObject* ExternalUnsignedShortArray::get(int index) {
2567 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2568}
2569
2570
ager@chromium.org3811b432009-10-28 14:53:37 +00002571void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2572 ASSERT((index >= 0) && (index < this->length()));
2573 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2574 ptr[index] = value;
2575}
2576
2577
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002578int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002579 ASSERT((index >= 0) && (index < this->length()));
2580 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2581 return ptr[index];
2582}
2583
2584
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002585MaybeObject* ExternalIntArray::get(int index) {
2586 return GetHeap()->NumberFromInt32(get_scalar(index));
2587}
2588
2589
ager@chromium.org3811b432009-10-28 14:53:37 +00002590void ExternalIntArray::set(int index, int32_t value) {
2591 ASSERT((index >= 0) && (index < this->length()));
2592 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2593 ptr[index] = value;
2594}
2595
2596
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002597uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002598 ASSERT((index >= 0) && (index < this->length()));
2599 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2600 return ptr[index];
2601}
2602
2603
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002604MaybeObject* ExternalUnsignedIntArray::get(int index) {
2605 return GetHeap()->NumberFromUint32(get_scalar(index));
2606}
2607
2608
ager@chromium.org3811b432009-10-28 14:53:37 +00002609void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2610 ASSERT((index >= 0) && (index < this->length()));
2611 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2612 ptr[index] = value;
2613}
2614
2615
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002616float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002617 ASSERT((index >= 0) && (index < this->length()));
2618 float* ptr = static_cast<float*>(external_pointer());
2619 return ptr[index];
2620}
2621
2622
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002623MaybeObject* ExternalFloatArray::get(int index) {
2624 return GetHeap()->NumberFromDouble(get_scalar(index));
2625}
2626
2627
ager@chromium.org3811b432009-10-28 14:53:37 +00002628void ExternalFloatArray::set(int index, float value) {
2629 ASSERT((index >= 0) && (index < this->length()));
2630 float* ptr = static_cast<float*>(external_pointer());
2631 ptr[index] = value;
2632}
2633
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002634
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002635double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002636 ASSERT((index >= 0) && (index < this->length()));
2637 double* ptr = static_cast<double*>(external_pointer());
2638 return ptr[index];
2639}
2640
2641
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002642MaybeObject* ExternalDoubleArray::get(int index) {
2643 return GetHeap()->NumberFromDouble(get_scalar(index));
2644}
2645
2646
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002647void ExternalDoubleArray::set(int index, double value) {
2648 ASSERT((index >= 0) && (index < this->length()));
2649 double* ptr = static_cast<double*>(external_pointer());
2650 ptr[index] = value;
2651}
2652
2653
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002654int Map::visitor_id() {
2655 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2656}
2657
2658
2659void Map::set_visitor_id(int id) {
2660 ASSERT(0 <= id && id < 256);
2661 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2662}
2663
ager@chromium.org3811b432009-10-28 14:53:37 +00002664
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002665int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002666 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2667}
2668
2669
2670int Map::inobject_properties() {
2671 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002672}
2673
2674
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002675int Map::pre_allocated_property_fields() {
2676 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2677}
2678
2679
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002680int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002681 int instance_size = map->instance_size();
2682 if (instance_size != kVariableSizeSentinel) return instance_size;
2683 // We can ignore the "symbol" bit becase it is only set for symbols
2684 // and implies a string type.
2685 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002686 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002687 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002688 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002689 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002690 if (instance_type == ASCII_STRING_TYPE) {
2691 return SeqAsciiString::SizeFor(
2692 reinterpret_cast<SeqAsciiString*>(this)->length());
2693 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002694 if (instance_type == BYTE_ARRAY_TYPE) {
2695 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2696 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002697 if (instance_type == STRING_TYPE) {
2698 return SeqTwoByteString::SizeFor(
2699 reinterpret_cast<SeqTwoByteString*>(this)->length());
2700 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002701 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2702 return FixedDoubleArray::SizeFor(
2703 reinterpret_cast<FixedDoubleArray*>(this)->length());
2704 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002705 ASSERT(instance_type == CODE_TYPE);
2706 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002707}
2708
2709
2710void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002711 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002712 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002713 ASSERT(0 <= value && value < 256);
2714 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2715}
2716
2717
ager@chromium.org7c537e22008-10-16 08:43:32 +00002718void Map::set_inobject_properties(int value) {
2719 ASSERT(0 <= value && value < 256);
2720 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2721}
2722
2723
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002724void Map::set_pre_allocated_property_fields(int value) {
2725 ASSERT(0 <= value && value < 256);
2726 WRITE_BYTE_FIELD(this,
2727 kPreAllocatedPropertyFieldsOffset,
2728 static_cast<byte>(value));
2729}
2730
2731
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002732InstanceType Map::instance_type() {
2733 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2734}
2735
2736
2737void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002738 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2739}
2740
2741
2742int Map::unused_property_fields() {
2743 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2744}
2745
2746
2747void Map::set_unused_property_fields(int value) {
2748 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2749}
2750
2751
2752byte Map::bit_field() {
2753 return READ_BYTE_FIELD(this, kBitFieldOffset);
2754}
2755
2756
2757void Map::set_bit_field(byte value) {
2758 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2759}
2760
2761
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002762byte Map::bit_field2() {
2763 return READ_BYTE_FIELD(this, kBitField2Offset);
2764}
2765
2766
2767void Map::set_bit_field2(byte value) {
2768 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2769}
2770
2771
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002772void Map::set_non_instance_prototype(bool value) {
2773 if (value) {
2774 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2775 } else {
2776 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2777 }
2778}
2779
2780
2781bool Map::has_non_instance_prototype() {
2782 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2783}
2784
2785
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002786void Map::set_function_with_prototype(bool value) {
2787 if (value) {
2788 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2789 } else {
2790 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2791 }
2792}
2793
2794
2795bool Map::function_with_prototype() {
2796 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2797}
2798
2799
ager@chromium.org870a0b62008-11-04 11:43:05 +00002800void Map::set_is_access_check_needed(bool access_check_needed) {
2801 if (access_check_needed) {
2802 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2803 } else {
2804 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2805 }
2806}
2807
2808
2809bool Map::is_access_check_needed() {
2810 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2811}
2812
2813
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002814void Map::set_is_extensible(bool value) {
2815 if (value) {
2816 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2817 } else {
2818 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2819 }
2820}
2821
2822bool Map::is_extensible() {
2823 return ((1 << kIsExtensible) & bit_field2()) != 0;
2824}
2825
2826
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002827void Map::set_attached_to_shared_function_info(bool value) {
2828 if (value) {
2829 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2830 } else {
2831 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2832 }
2833}
2834
2835bool Map::attached_to_shared_function_info() {
2836 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2837}
2838
2839
2840void Map::set_is_shared(bool value) {
2841 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002842 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002843 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002844 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002845 }
2846}
2847
2848bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002849 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002850}
2851
2852
2853JSFunction* Map::unchecked_constructor() {
2854 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2855}
2856
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002857
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002858FixedArray* Map::unchecked_prototype_transitions() {
2859 return reinterpret_cast<FixedArray*>(
2860 READ_FIELD(this, kPrototypeTransitionsOffset));
2861}
2862
2863
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002864Code::Flags Code::flags() {
2865 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2866}
2867
2868
2869void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002870 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002871 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002872 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2873 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002874 ExtractArgumentsCountFromFlags(flags) >= 0);
2875 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2876}
2877
2878
2879Code::Kind Code::kind() {
2880 return ExtractKindFromFlags(flags());
2881}
2882
2883
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002884InLoopFlag Code::ic_in_loop() {
2885 return ExtractICInLoopFromFlags(flags());
2886}
2887
2888
kasper.lund7276f142008-07-30 08:49:36 +00002889InlineCacheState Code::ic_state() {
2890 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002891 // Only allow uninitialized or debugger states for non-IC code
2892 // objects. This is used in the debugger to determine whether or not
2893 // a call to code object has been replaced with a debug break call.
2894 ASSERT(is_inline_cache_stub() ||
2895 result == UNINITIALIZED ||
2896 result == DEBUG_BREAK ||
2897 result == DEBUG_PREPARE_STEP_IN);
2898 return result;
2899}
2900
2901
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002902Code::ExtraICState Code::extra_ic_state() {
2903 ASSERT(is_inline_cache_stub());
2904 return ExtractExtraICStateFromFlags(flags());
2905}
2906
2907
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002908PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002909 return ExtractTypeFromFlags(flags());
2910}
2911
2912
2913int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002914 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002915 return ExtractArgumentsCountFromFlags(flags());
2916}
2917
2918
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002919int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002920 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002921 kind() == UNARY_OP_IC ||
2922 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002923 kind() == COMPARE_IC ||
2924 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002925 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002926}
2927
2928
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002929void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002930 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002931 kind() == UNARY_OP_IC ||
2932 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002933 kind() == COMPARE_IC ||
2934 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002935 ASSERT(0 <= major && major < 256);
2936 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002937}
2938
2939
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002940bool Code::optimizable() {
2941 ASSERT(kind() == FUNCTION);
2942 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2943}
2944
2945
2946void Code::set_optimizable(bool value) {
2947 ASSERT(kind() == FUNCTION);
2948 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2949}
2950
2951
2952bool Code::has_deoptimization_support() {
2953 ASSERT(kind() == FUNCTION);
2954 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2955}
2956
2957
2958void Code::set_has_deoptimization_support(bool value) {
2959 ASSERT(kind() == FUNCTION);
2960 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2961}
2962
2963
2964int Code::allow_osr_at_loop_nesting_level() {
2965 ASSERT(kind() == FUNCTION);
2966 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2967}
2968
2969
2970void Code::set_allow_osr_at_loop_nesting_level(int level) {
2971 ASSERT(kind() == FUNCTION);
2972 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2973 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2974}
2975
2976
2977unsigned Code::stack_slots() {
2978 ASSERT(kind() == OPTIMIZED_FUNCTION);
2979 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2980}
2981
2982
2983void Code::set_stack_slots(unsigned slots) {
2984 ASSERT(kind() == OPTIMIZED_FUNCTION);
2985 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2986}
2987
2988
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002989unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002990 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002991 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002992}
2993
2994
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002995void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002996 ASSERT(kind() == OPTIMIZED_FUNCTION);
2997 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002998 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002999}
3000
3001
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003002unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003003 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003004 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003005}
3006
3007
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003008void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003009 ASSERT(kind() == FUNCTION);
3010 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003011 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003012}
3013
3014
3015CheckType Code::check_type() {
3016 ASSERT(is_call_stub() || is_keyed_call_stub());
3017 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3018 return static_cast<CheckType>(type);
3019}
3020
3021
3022void Code::set_check_type(CheckType value) {
3023 ASSERT(is_call_stub() || is_keyed_call_stub());
3024 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3025}
3026
3027
danno@chromium.org40cb8782011-05-25 07:58:50 +00003028byte Code::unary_op_type() {
3029 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003030 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3031}
3032
3033
danno@chromium.org40cb8782011-05-25 07:58:50 +00003034void Code::set_unary_op_type(byte value) {
3035 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003036 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3037}
3038
3039
danno@chromium.org40cb8782011-05-25 07:58:50 +00003040byte Code::binary_op_type() {
3041 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003042 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3043}
3044
3045
danno@chromium.org40cb8782011-05-25 07:58:50 +00003046void Code::set_binary_op_type(byte value) {
3047 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003048 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3049}
3050
3051
danno@chromium.org40cb8782011-05-25 07:58:50 +00003052byte Code::binary_op_result_type() {
3053 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003054 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3055}
3056
3057
danno@chromium.org40cb8782011-05-25 07:58:50 +00003058void Code::set_binary_op_result_type(byte value) {
3059 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003060 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3061}
3062
3063
3064byte Code::compare_state() {
3065 ASSERT(is_compare_ic_stub());
3066 return READ_BYTE_FIELD(this, kCompareStateOffset);
3067}
3068
3069
3070void Code::set_compare_state(byte value) {
3071 ASSERT(is_compare_ic_stub());
3072 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3073}
3074
3075
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003076byte Code::to_boolean_state() {
3077 ASSERT(is_to_boolean_ic_stub());
3078 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3079}
3080
3081
3082void Code::set_to_boolean_state(byte value) {
3083 ASSERT(is_to_boolean_ic_stub());
3084 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3085}
3086
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003087bool Code::is_inline_cache_stub() {
3088 Kind kind = this->kind();
3089 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3090}
3091
3092
3093Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003094 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00003095 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003096 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003097 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003098 int argc,
3099 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003100 // Extra IC state is only allowed for call IC stubs or for store IC
3101 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003102 ASSERT(extra_ic_state == kNoExtraICState ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003103 (kind == CALL_IC) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00003104 (kind == STORE_IC) ||
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003105 (kind == KEYED_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003106 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003107 int bits = KindField::encode(kind)
3108 | ICInLoopField::encode(in_loop)
3109 | ICStateField::encode(ic_state)
3110 | TypeField::encode(type)
3111 | ExtraICStateField::encode(extra_ic_state)
3112 | (argc << kFlagsArgumentsCountShift)
3113 | CacheHolderField::encode(holder);
3114 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003115}
3116
3117
3118Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3119 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003120 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003121 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003122 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003123 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003124 return ComputeFlags(
3125 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003126}
3127
3128
3129Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003130 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003131}
3132
3133
kasper.lund7276f142008-07-30 08:49:36 +00003134InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003135 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003136}
3137
3138
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003139Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003140 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003141}
3142
3143
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003144InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003145 return ICInLoopField::decode(flags);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003146}
3147
3148
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003149PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003150 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003151}
3152
3153
3154int Code::ExtractArgumentsCountFromFlags(Flags flags) {
3155 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
3156}
3157
3158
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003159InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003160 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003161}
3162
3163
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003164Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003165 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003166 return static_cast<Flags>(bits);
3167}
3168
3169
ager@chromium.org8bb60582008-12-11 12:02:20 +00003170Code* Code::GetCodeFromTargetAddress(Address address) {
3171 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3172 // GetCodeFromTargetAddress might be called when marking objects during mark
3173 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3174 // Code::cast. Code::cast does not work when the object's map is
3175 // marked.
3176 Code* result = reinterpret_cast<Code*>(code);
3177 return result;
3178}
3179
3180
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003181Isolate* Map::isolate() {
3182 return heap()->isolate();
3183}
3184
3185
3186Heap* Map::heap() {
3187 // NOTE: address() helper is not used to save one instruction.
3188 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3189 ASSERT(heap != NULL);
3190 ASSERT(heap->isolate() == Isolate::Current());
3191 return heap;
3192}
3193
3194
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003195Heap* Code::heap() {
3196 // NOTE: address() helper is not used to save one instruction.
3197 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3198 ASSERT(heap != NULL);
3199 ASSERT(heap->isolate() == Isolate::Current());
3200 return heap;
3201}
3202
3203
3204Isolate* Code::isolate() {
3205 return heap()->isolate();
3206}
3207
3208
3209Heap* JSGlobalPropertyCell::heap() {
3210 // NOTE: address() helper is not used to save one instruction.
3211 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3212 ASSERT(heap != NULL);
3213 ASSERT(heap->isolate() == Isolate::Current());
3214 return heap;
3215}
3216
3217
3218Isolate* JSGlobalPropertyCell::isolate() {
3219 return heap()->isolate();
3220}
3221
3222
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003223Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3224 return HeapObject::
3225 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3226}
3227
3228
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003229Object* Map::prototype() {
3230 return READ_FIELD(this, kPrototypeOffset);
3231}
3232
3233
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003234void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003235 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003236 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003237 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003238}
3239
3240
lrn@chromium.org303ada72010-10-27 09:33:13 +00003241MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003242 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003243 Object* obj;
3244 { MaybeObject* maybe_obj = CopyDropTransitions();
3245 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3246 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003247 Map* new_map = Map::cast(obj);
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003248 new_map->set_elements_kind(FAST_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003249 isolate()->counters()->map_to_fast_elements()->Increment();
3250 return new_map;
3251}
3252
3253
3254MaybeObject* Map::GetFastDoubleElementsMap() {
3255 if (has_fast_double_elements()) return this;
3256 Object* obj;
3257 { MaybeObject* maybe_obj = CopyDropTransitions();
3258 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3259 }
3260 Map* new_map = Map::cast(obj);
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003261 new_map->set_elements_kind(FAST_DOUBLE_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003262 isolate()->counters()->map_to_fast_double_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003263 return new_map;
3264}
3265
3266
lrn@chromium.org303ada72010-10-27 09:33:13 +00003267MaybeObject* Map::GetSlowElementsMap() {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003268 if (!has_fast_elements() && !has_fast_double_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003269 Object* obj;
3270 { MaybeObject* maybe_obj = CopyDropTransitions();
3271 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3272 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003273 Map* new_map = Map::cast(obj);
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003274 new_map->set_elements_kind(DICTIONARY_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003275 isolate()->counters()->map_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003276 return new_map;
3277}
3278
3279
danno@chromium.org40cb8782011-05-25 07:58:50 +00003280DescriptorArray* Map::instance_descriptors() {
3281 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3282 if (object->IsSmi()) {
3283 return HEAP->empty_descriptor_array();
3284 } else {
3285 return DescriptorArray::cast(object);
3286 }
3287}
3288
3289
3290void Map::init_instance_descriptors() {
3291 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3292}
3293
3294
3295void Map::clear_instance_descriptors() {
3296 Object* object = READ_FIELD(this,
3297 kInstanceDescriptorsOrBitField3Offset);
3298 if (!object->IsSmi()) {
3299 WRITE_FIELD(
3300 this,
3301 kInstanceDescriptorsOrBitField3Offset,
3302 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3303 }
3304}
3305
3306
3307void Map::set_instance_descriptors(DescriptorArray* value,
3308 WriteBarrierMode mode) {
3309 Object* object = READ_FIELD(this,
3310 kInstanceDescriptorsOrBitField3Offset);
3311 if (value == isolate()->heap()->empty_descriptor_array()) {
3312 clear_instance_descriptors();
3313 return;
3314 } else {
3315 if (object->IsSmi()) {
3316 value->set_bit_field3_storage(Smi::cast(object)->value());
3317 } else {
3318 value->set_bit_field3_storage(
3319 DescriptorArray::cast(object)->bit_field3_storage());
3320 }
3321 }
3322 ASSERT(!is_shared());
3323 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
3324 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3325 this,
3326 kInstanceDescriptorsOrBitField3Offset,
3327 mode);
3328}
3329
3330
3331int Map::bit_field3() {
3332 Object* object = READ_FIELD(this,
3333 kInstanceDescriptorsOrBitField3Offset);
3334 if (object->IsSmi()) {
3335 return Smi::cast(object)->value();
3336 } else {
3337 return DescriptorArray::cast(object)->bit_field3_storage();
3338 }
3339}
3340
3341
3342void Map::set_bit_field3(int value) {
3343 ASSERT(Smi::IsValid(value));
3344 Object* object = READ_FIELD(this,
3345 kInstanceDescriptorsOrBitField3Offset);
3346 if (object->IsSmi()) {
3347 WRITE_FIELD(this,
3348 kInstanceDescriptorsOrBitField3Offset,
3349 Smi::FromInt(value));
3350 } else {
3351 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3352 }
3353}
3354
3355
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003356ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003357ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003358ACCESSORS(Map, constructor, Object, kConstructorOffset)
3359
3360ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
3361ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003362ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
3363 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003364
3365ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3366ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003367ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003368
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003369ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003370
3371ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3372ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3373ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3374ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3375ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3376
3377ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3378ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3379ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3380
3381ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3382ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3383ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3384ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3385ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3386ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3387
3388ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3389ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3390
3391ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3392ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3393
3394ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3395ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003396ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3397 kPropertyAccessorsOffset)
3398ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3399 kPrototypeTemplateOffset)
3400ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3401ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3402 kNamedPropertyHandlerOffset)
3403ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3404 kIndexedPropertyHandlerOffset)
3405ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3406 kInstanceTemplateOffset)
3407ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3408ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003409ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3410 kInstanceCallHandlerOffset)
3411ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3412 kAccessCheckInfoOffset)
3413ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3414
3415ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003416ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3417 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003418
3419ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3420ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3421
3422ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3423
3424ACCESSORS(Script, source, Object, kSourceOffset)
3425ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003426ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003427ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3428ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003429ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003430ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003431ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003432ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003433ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003434ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003435ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003436ACCESSORS(Script, eval_from_instructions_offset, Smi,
3437 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003438
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003439#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003440ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3441ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3442ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3443ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3444
3445ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3446ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3447ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3448ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003449#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003450
3451ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003452ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3453ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003454ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3455 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003456ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003457ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3458ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003459ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003460ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3461 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003462
3463BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3464 kHiddenPrototypeBit)
3465BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3466BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3467 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003468BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3469 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003470BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3471 kIsExpressionBit)
3472BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3473 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003474BOOL_GETTER(SharedFunctionInfo,
3475 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003476 has_only_simple_this_property_assignments,
3477 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003478BOOL_ACCESSORS(SharedFunctionInfo,
3479 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003480 allows_lazy_compilation,
3481 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003482BOOL_ACCESSORS(SharedFunctionInfo,
3483 compiler_hints,
3484 uses_arguments,
3485 kUsesArguments)
3486BOOL_ACCESSORS(SharedFunctionInfo,
3487 compiler_hints,
3488 has_duplicate_parameters,
3489 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003490
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003491
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003492#if V8_HOST_ARCH_32_BIT
3493SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3494SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003495 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003496SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003497 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003498SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3499SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003500 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003501SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3502SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003503 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003504SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003505 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003506SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003507 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003508SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003509#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003510
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003511#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003512 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003513 int holder::name() { \
3514 int value = READ_INT_FIELD(this, offset); \
3515 ASSERT(kHeapObjectTag == 1); \
3516 ASSERT((value & kHeapObjectTag) == 0); \
3517 return value >> 1; \
3518 } \
3519 void holder::set_##name(int value) { \
3520 ASSERT(kHeapObjectTag == 1); \
3521 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3522 (value & 0xC0000000) == 0x000000000); \
3523 WRITE_INT_FIELD(this, \
3524 offset, \
3525 (value << 1) & ~kHeapObjectTag); \
3526 }
3527
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003528#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3529 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003530 INT_ACCESSORS(holder, name, offset)
3531
3532
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003533PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003534PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3535 formal_parameter_count,
3536 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003537
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003538PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3539 expected_nof_properties,
3540 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003541PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3542
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003543PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3544PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3545 start_position_and_type,
3546 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003547
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003548PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3549 function_token_position,
3550 kFunctionTokenPositionOffset)
3551PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3552 compiler_hints,
3553 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003554
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003555PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3556 this_property_assignments_count,
3557 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003558PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003559#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003560
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003561
3562int SharedFunctionInfo::construction_count() {
3563 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3564}
3565
3566
3567void SharedFunctionInfo::set_construction_count(int value) {
3568 ASSERT(0 <= value && value < 256);
3569 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3570}
3571
3572
whesse@chromium.org7b260152011-06-20 15:33:18 +00003573BOOL_ACCESSORS(SharedFunctionInfo,
3574 compiler_hints,
3575 live_objects_may_exist,
3576 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003577
3578
3579bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003580 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003581}
3582
3583
whesse@chromium.org7b260152011-06-20 15:33:18 +00003584BOOL_GETTER(SharedFunctionInfo,
3585 compiler_hints,
3586 optimization_disabled,
3587 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003588
3589
3590void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3591 set_compiler_hints(BooleanBit::set(compiler_hints(),
3592 kOptimizationDisabled,
3593 disable));
3594 // If disabling optimizations we reflect that in the code object so
3595 // it will not be counted as optimizable code.
3596 if ((code()->kind() == Code::FUNCTION) && disable) {
3597 code()->set_optimizable(false);
3598 }
3599}
3600
3601
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003602BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, strict_mode,
whesse@chromium.org7b260152011-06-20 15:33:18 +00003603 kStrictModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003604BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3605BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3606 name_should_print_as_anonymous,
3607 kNameShouldPrintAsAnonymous)
3608BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3609BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003610
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003611ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3612ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3613
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003614ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3615
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003616bool Script::HasValidSource() {
3617 Object* src = this->source();
3618 if (!src->IsString()) return true;
3619 String* src_str = String::cast(src);
3620 if (!StringShape(src_str).IsExternal()) return true;
3621 if (src_str->IsAsciiRepresentation()) {
3622 return ExternalAsciiString::cast(src)->resource() != NULL;
3623 } else if (src_str->IsTwoByteRepresentation()) {
3624 return ExternalTwoByteString::cast(src)->resource() != NULL;
3625 }
3626 return true;
3627}
3628
3629
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003630void SharedFunctionInfo::DontAdaptArguments() {
3631 ASSERT(code()->kind() == Code::BUILTIN);
3632 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3633}
3634
3635
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003636int SharedFunctionInfo::start_position() {
3637 return start_position_and_type() >> kStartPositionShift;
3638}
3639
3640
3641void SharedFunctionInfo::set_start_position(int start_position) {
3642 set_start_position_and_type((start_position << kStartPositionShift)
3643 | (start_position_and_type() & ~kStartPositionMask));
3644}
3645
3646
3647Code* SharedFunctionInfo::code() {
3648 return Code::cast(READ_FIELD(this, kCodeOffset));
3649}
3650
3651
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003652Code* SharedFunctionInfo::unchecked_code() {
3653 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3654}
3655
3656
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003657void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003658 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003659 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003660}
3661
3662
ager@chromium.orgb5737492010-07-15 09:29:43 +00003663SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3664 return reinterpret_cast<SerializedScopeInfo*>(
3665 READ_FIELD(this, kScopeInfoOffset));
3666}
3667
3668
3669void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3670 WriteBarrierMode mode) {
3671 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003672 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003673}
3674
3675
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003676Smi* SharedFunctionInfo::deopt_counter() {
3677 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3678}
3679
3680
3681void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3682 WRITE_FIELD(this, kDeoptCounterOffset, value);
3683}
3684
3685
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003686bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003687 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003688 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003689}
3690
3691
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003692bool SharedFunctionInfo::IsApiFunction() {
3693 return function_data()->IsFunctionTemplateInfo();
3694}
3695
3696
3697FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3698 ASSERT(IsApiFunction());
3699 return FunctionTemplateInfo::cast(function_data());
3700}
3701
3702
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003703bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003704 return function_data()->IsSmi();
3705}
3706
3707
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003708BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3709 ASSERT(HasBuiltinFunctionId());
3710 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003711}
3712
3713
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003714int SharedFunctionInfo::code_age() {
3715 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3716}
3717
3718
3719void SharedFunctionInfo::set_code_age(int code_age) {
3720 set_compiler_hints(compiler_hints() |
3721 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3722}
3723
3724
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003725bool SharedFunctionInfo::has_deoptimization_support() {
3726 Code* code = this->code();
3727 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3728}
3729
3730
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003731bool JSFunction::IsBuiltin() {
3732 return context()->global()->IsJSBuiltinsObject();
3733}
3734
3735
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003736bool JSFunction::NeedsArgumentsAdaption() {
3737 return shared()->formal_parameter_count() !=
3738 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3739}
3740
3741
3742bool JSFunction::IsOptimized() {
3743 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3744}
3745
3746
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003747bool JSFunction::IsOptimizable() {
3748 return code()->kind() == Code::FUNCTION && code()->optimizable();
3749}
3750
3751
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003752bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003753 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003754}
3755
3756
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003757Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003758 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003759}
3760
3761
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003762Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003763 return reinterpret_cast<Code*>(
3764 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003765}
3766
3767
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003768void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003769 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003770 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003771 Address entry = value->entry();
3772 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003773}
3774
3775
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003776void JSFunction::ReplaceCode(Code* code) {
3777 bool was_optimized = IsOptimized();
3778 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3779
3780 set_code(code);
3781
3782 // Add/remove the function from the list of optimized functions for this
3783 // context based on the state change.
3784 if (!was_optimized && is_optimized) {
3785 context()->global_context()->AddOptimizedFunction(this);
3786 }
3787 if (was_optimized && !is_optimized) {
3788 context()->global_context()->RemoveOptimizedFunction(this);
3789 }
3790}
3791
3792
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003793Context* JSFunction::context() {
3794 return Context::cast(READ_FIELD(this, kContextOffset));
3795}
3796
3797
3798Object* JSFunction::unchecked_context() {
3799 return READ_FIELD(this, kContextOffset);
3800}
3801
3802
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003803SharedFunctionInfo* JSFunction::unchecked_shared() {
3804 return reinterpret_cast<SharedFunctionInfo*>(
3805 READ_FIELD(this, kSharedFunctionInfoOffset));
3806}
3807
3808
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003809void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003810 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003811 WRITE_FIELD(this, kContextOffset, value);
3812 WRITE_BARRIER(this, kContextOffset);
3813}
3814
3815ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3816 kPrototypeOrInitialMapOffset)
3817
3818
3819Map* JSFunction::initial_map() {
3820 return Map::cast(prototype_or_initial_map());
3821}
3822
3823
3824void JSFunction::set_initial_map(Map* value) {
3825 set_prototype_or_initial_map(value);
3826}
3827
3828
3829bool JSFunction::has_initial_map() {
3830 return prototype_or_initial_map()->IsMap();
3831}
3832
3833
3834bool JSFunction::has_instance_prototype() {
3835 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3836}
3837
3838
3839bool JSFunction::has_prototype() {
3840 return map()->has_non_instance_prototype() || has_instance_prototype();
3841}
3842
3843
3844Object* JSFunction::instance_prototype() {
3845 ASSERT(has_instance_prototype());
3846 if (has_initial_map()) return initial_map()->prototype();
3847 // When there is no initial map and the prototype is a JSObject, the
3848 // initial map field is used for the prototype field.
3849 return prototype_or_initial_map();
3850}
3851
3852
3853Object* JSFunction::prototype() {
3854 ASSERT(has_prototype());
3855 // If the function's prototype property has been set to a non-JSObject
3856 // value, that value is stored in the constructor field of the map.
3857 if (map()->has_non_instance_prototype()) return map()->constructor();
3858 return instance_prototype();
3859}
3860
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003861bool JSFunction::should_have_prototype() {
3862 return map()->function_with_prototype();
3863}
3864
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003865
3866bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003867 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003868}
3869
3870
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003871int JSFunction::NumberOfLiterals() {
3872 return literals()->length();
3873}
3874
3875
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003876Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003877 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003878 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003879}
3880
3881
3882void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3883 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003884 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003885 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3886 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3887}
3888
3889
3890Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003891 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003892 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3893}
3894
3895
3896void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3897 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003898 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003899 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003900 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003901}
3902
3903
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003904ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003905ACCESSORS(JSProxy, padding, Object, kPaddingOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003906
3907
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003908ACCESSORS(JSWeakMap, table, ObjectHashTable, kTableOffset)
3909ACCESSORS_GCSAFE(JSWeakMap, next, Object, kNextOffset)
3910
3911
3912ObjectHashTable* JSWeakMap::unchecked_table() {
3913 return reinterpret_cast<ObjectHashTable*>(READ_FIELD(this, kTableOffset));
3914}
3915
3916
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003917Address Foreign::address() {
3918 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003919}
3920
3921
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003922void Foreign::set_address(Address value) {
3923 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003924}
3925
3926
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003927ACCESSORS(JSValue, value, Object, kValueOffset)
3928
3929
3930JSValue* JSValue::cast(Object* obj) {
3931 ASSERT(obj->IsJSValue());
3932 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3933 return reinterpret_cast<JSValue*>(obj);
3934}
3935
3936
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003937ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3938ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3939ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3940ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3941ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3942SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3943SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3944
3945
3946JSMessageObject* JSMessageObject::cast(Object* obj) {
3947 ASSERT(obj->IsJSMessageObject());
3948 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3949 return reinterpret_cast<JSMessageObject*>(obj);
3950}
3951
3952
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003953INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003954ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003955ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003956ACCESSORS(Code, next_code_flushing_candidate,
3957 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003958
3959
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003960byte* Code::instruction_start() {
3961 return FIELD_ADDR(this, kHeaderSize);
3962}
3963
3964
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003965byte* Code::instruction_end() {
3966 return instruction_start() + instruction_size();
3967}
3968
3969
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003970int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003971 return RoundUp(instruction_size(), kObjectAlignment);
3972}
3973
3974
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003975FixedArray* Code::unchecked_deoptimization_data() {
3976 return reinterpret_cast<FixedArray*>(
3977 READ_FIELD(this, kDeoptimizationDataOffset));
3978}
3979
3980
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003981ByteArray* Code::unchecked_relocation_info() {
3982 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003983}
3984
3985
3986byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003987 return unchecked_relocation_info()->GetDataStartAddress();
3988}
3989
3990
3991int Code::relocation_size() {
3992 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003993}
3994
3995
3996byte* Code::entry() {
3997 return instruction_start();
3998}
3999
4000
4001bool Code::contains(byte* pc) {
4002 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00004003 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004004}
4005
4006
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004007ACCESSORS(JSArray, length, Object, kLengthOffset)
4008
4009
ager@chromium.org236ad962008-09-25 09:45:57 +00004010ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004011
4012
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004013JSRegExp::Type JSRegExp::TypeTag() {
4014 Object* data = this->data();
4015 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4016 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4017 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004018}
4019
4020
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004021JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4022 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4023 return static_cast<JSRegExp::Type>(smi->value());
4024}
4025
4026
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004027int JSRegExp::CaptureCount() {
4028 switch (TypeTag()) {
4029 case ATOM:
4030 return 0;
4031 case IRREGEXP:
4032 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4033 default:
4034 UNREACHABLE();
4035 return -1;
4036 }
4037}
4038
4039
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004040JSRegExp::Flags JSRegExp::GetFlags() {
4041 ASSERT(this->data()->IsFixedArray());
4042 Object* data = this->data();
4043 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4044 return Flags(smi->value());
4045}
4046
4047
4048String* JSRegExp::Pattern() {
4049 ASSERT(this->data()->IsFixedArray());
4050 Object* data = this->data();
4051 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4052 return pattern;
4053}
4054
4055
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004056Object* JSRegExp::DataAt(int index) {
4057 ASSERT(TypeTag() != NOT_COMPILED);
4058 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004059}
4060
4061
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004062Object* JSRegExp::DataAtUnchecked(int index) {
4063 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4064 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4065 return READ_FIELD(fa, offset);
4066}
4067
4068
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004069void JSRegExp::SetDataAt(int index, Object* value) {
4070 ASSERT(TypeTag() != NOT_COMPILED);
4071 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4072 FixedArray::cast(data())->set(index, value);
4073}
4074
4075
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004076void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4077 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4078 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4079 if (value->IsSmi()) {
4080 fa->set_unchecked(index, Smi::cast(value));
4081 } else {
4082 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4083 }
4084}
4085
4086
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004087ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004088 ElementsKind kind = map()->elements_kind();
4089 ASSERT((kind == FAST_ELEMENTS &&
4090 (elements()->map() == GetHeap()->fixed_array_map() ||
4091 elements()->map() == GetHeap()->fixed_cow_array_map())) ||
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004092 (kind == FAST_DOUBLE_ELEMENTS &&
4093 elements()->IsFixedDoubleArray()) ||
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004094 (kind == DICTIONARY_ELEMENTS &&
4095 elements()->IsFixedArray() &&
4096 elements()->IsDictionary()) ||
4097 (kind > DICTIONARY_ELEMENTS));
4098 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004099}
4100
4101
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004102ElementsAccessor* JSObject::GetElementsAccessor() {
4103 return ElementsAccessor::ForKind(GetElementsKind());
4104}
4105
4106
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004107bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004108 return GetElementsKind() == FAST_ELEMENTS;
4109}
4110
4111
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004112bool JSObject::HasFastDoubleElements() {
4113 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4114}
4115
4116
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004117bool JSObject::HasDictionaryElements() {
4118 return GetElementsKind() == DICTIONARY_ELEMENTS;
4119}
4120
4121
ager@chromium.org3811b432009-10-28 14:53:37 +00004122bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004123 HeapObject* array = elements();
4124 ASSERT(array != NULL);
4125 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004126}
4127
4128
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004129#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4130bool JSObject::HasExternal##name##Elements() { \
4131 HeapObject* array = elements(); \
4132 ASSERT(array != NULL); \
4133 if (!array->IsHeapObject()) \
4134 return false; \
4135 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004136}
4137
4138
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004139EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4140EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4141EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4142EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4143 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4144EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4145EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4146 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4147EXTERNAL_ELEMENTS_CHECK(Float,
4148 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004149EXTERNAL_ELEMENTS_CHECK(Double,
4150 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004151EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004152
4153
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004154bool JSObject::HasNamedInterceptor() {
4155 return map()->has_named_interceptor();
4156}
4157
4158
4159bool JSObject::HasIndexedInterceptor() {
4160 return map()->has_indexed_interceptor();
4161}
4162
4163
ager@chromium.org5c838252010-02-19 08:53:10 +00004164bool JSObject::AllowsSetElementsLength() {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004165 bool result = elements()->IsFixedArray() ||
4166 elements()->IsFixedDoubleArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004167 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00004168 return result;
4169}
4170
4171
lrn@chromium.org303ada72010-10-27 09:33:13 +00004172MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004173 ASSERT(HasFastElements());
4174 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004175 Isolate* isolate = GetIsolate();
4176 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004177 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004178 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4179 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004180 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4181 return maybe_writable_elems;
4182 }
4183 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004184 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004185 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004186 return writable_elems;
4187}
4188
4189
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004190StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004191 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004192 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004193}
4194
4195
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004196NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004197 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004198 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004199}
4200
4201
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004202bool String::IsHashFieldComputed(uint32_t field) {
4203 return (field & kHashNotComputedMask) == 0;
4204}
4205
4206
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004207bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004208 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004209}
4210
4211
4212uint32_t String::Hash() {
4213 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004214 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004215 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004216 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004217 return ComputeAndSetHash();
4218}
4219
4220
ager@chromium.org7c537e22008-10-16 08:43:32 +00004221StringHasher::StringHasher(int length)
4222 : length_(length),
4223 raw_running_hash_(0),
4224 array_index_(0),
4225 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4226 is_first_char_(true),
4227 is_valid_(true) { }
4228
4229
4230bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004231 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004232}
4233
4234
4235void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004236 // Use the Jenkins one-at-a-time hash function to update the hash
4237 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004238 raw_running_hash_ += c;
4239 raw_running_hash_ += (raw_running_hash_ << 10);
4240 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004241 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004242 if (is_array_index_) {
4243 if (c < '0' || c > '9') {
4244 is_array_index_ = false;
4245 } else {
4246 int d = c - '0';
4247 if (is_first_char_) {
4248 is_first_char_ = false;
4249 if (c == '0' && length_ > 1) {
4250 is_array_index_ = false;
4251 return;
4252 }
4253 }
4254 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4255 is_array_index_ = false;
4256 } else {
4257 array_index_ = array_index_ * 10 + d;
4258 }
4259 }
4260 }
4261}
4262
4263
4264void StringHasher::AddCharacterNoIndex(uc32 c) {
4265 ASSERT(!is_array_index());
4266 raw_running_hash_ += c;
4267 raw_running_hash_ += (raw_running_hash_ << 10);
4268 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4269}
4270
4271
4272uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004273 // Get the calculated raw hash value and do some more bit ops to distribute
4274 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004275 uint32_t result = raw_running_hash_;
4276 result += (result << 3);
4277 result ^= (result >> 11);
4278 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004279 if (result == 0) {
4280 result = 27;
4281 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004282 return result;
4283}
4284
4285
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004286template <typename schar>
4287uint32_t HashSequentialString(const schar* chars, int length) {
4288 StringHasher hasher(length);
4289 if (!hasher.has_trivial_hash()) {
4290 int i;
4291 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4292 hasher.AddCharacter(chars[i]);
4293 }
4294 for (; i < length; i++) {
4295 hasher.AddCharacterNoIndex(chars[i]);
4296 }
4297 }
4298 return hasher.GetHashField();
4299}
4300
4301
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004302bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004303 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004304 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4305 return false;
4306 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004307 return SlowAsArrayIndex(index);
4308}
4309
4310
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004311Object* JSReceiver::GetPrototype() {
4312 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004313}
4314
4315
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004316bool JSReceiver::HasProperty(String* name) {
4317 if (IsJSProxy()) {
4318 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4319 }
4320 return GetPropertyAttribute(name) != ABSENT;
4321}
4322
4323
4324bool JSReceiver::HasLocalProperty(String* name) {
4325 if (IsJSProxy()) {
4326 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4327 }
4328 return GetLocalPropertyAttribute(name) != ABSENT;
4329}
4330
4331
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004332PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004333 return GetPropertyAttributeWithReceiver(this, key);
4334}
4335
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004336// TODO(504): this may be useful in other places too where JSGlobalProxy
4337// is used.
4338Object* JSObject::BypassGlobalProxy() {
4339 if (IsJSGlobalProxy()) {
4340 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004341 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004342 ASSERT(proto->IsJSGlobalObject());
4343 return proto;
4344 }
4345 return this;
4346}
4347
4348
4349bool JSObject::HasHiddenPropertiesObject() {
4350 ASSERT(!IsJSGlobalProxy());
4351 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004352 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004353 false) != ABSENT;
4354}
4355
4356
4357Object* JSObject::GetHiddenPropertiesObject() {
4358 ASSERT(!IsJSGlobalProxy());
4359 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004360 // You can't install a getter on a property indexed by the hidden symbol,
4361 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
4362 // object.
4363 Object* result =
4364 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004365 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00004366 &attributes)->ToObjectUnchecked();
4367 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004368}
4369
4370
lrn@chromium.org303ada72010-10-27 09:33:13 +00004371MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004372 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004373 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004374 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00004375 DONT_ENUM,
4376 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004377}
4378
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004379
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004380bool JSObject::HasHiddenProperties() {
4381 return !GetHiddenProperties(OMIT_CREATION)->ToObjectChecked()->IsUndefined();
4382}
4383
4384
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004385bool JSObject::HasElement(uint32_t index) {
4386 return HasElementWithReceiver(this, index);
4387}
4388
4389
4390bool AccessorInfo::all_can_read() {
4391 return BooleanBit::get(flag(), kAllCanReadBit);
4392}
4393
4394
4395void AccessorInfo::set_all_can_read(bool value) {
4396 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4397}
4398
4399
4400bool AccessorInfo::all_can_write() {
4401 return BooleanBit::get(flag(), kAllCanWriteBit);
4402}
4403
4404
4405void AccessorInfo::set_all_can_write(bool value) {
4406 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4407}
4408
4409
ager@chromium.org870a0b62008-11-04 11:43:05 +00004410bool AccessorInfo::prohibits_overwriting() {
4411 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4412}
4413
4414
4415void AccessorInfo::set_prohibits_overwriting(bool value) {
4416 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4417}
4418
4419
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004420PropertyAttributes AccessorInfo::property_attributes() {
4421 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4422}
4423
4424
4425void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004426 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004427}
4428
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004429
4430template<typename Shape, typename Key>
4431void Dictionary<Shape, Key>::SetEntry(int entry,
4432 Object* key,
4433 Object* value) {
4434 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4435}
4436
4437
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004438template<typename Shape, typename Key>
4439void Dictionary<Shape, Key>::SetEntry(int entry,
4440 Object* key,
4441 Object* value,
4442 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004443 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004444 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004445 AssertNoAllocation no_gc;
4446 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004447 FixedArray::set(index, key, mode);
4448 FixedArray::set(index+1, value, mode);
4449 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004450}
4451
4452
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004453bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4454 ASSERT(other->IsNumber());
4455 return key == static_cast<uint32_t>(other->Number());
4456}
4457
4458
4459uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4460 return ComputeIntegerHash(key);
4461}
4462
4463
4464uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4465 ASSERT(other->IsNumber());
4466 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4467}
4468
4469
4470MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4471 return Isolate::Current()->heap()->NumberFromUint32(key);
4472}
4473
4474
4475bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4476 // We know that all entries in a hash table had their hash keys created.
4477 // Use that knowledge to have fast failure.
4478 if (key->Hash() != String::cast(other)->Hash()) return false;
4479 return key->Equals(String::cast(other));
4480}
4481
4482
4483uint32_t StringDictionaryShape::Hash(String* key) {
4484 return key->Hash();
4485}
4486
4487
4488uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4489 return String::cast(other)->Hash();
4490}
4491
4492
4493MaybeObject* StringDictionaryShape::AsObject(String* key) {
4494 return key;
4495}
4496
4497
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004498bool ObjectHashTableShape::IsMatch(JSObject* key, Object* other) {
4499 return key == JSObject::cast(other);
4500}
4501
4502
4503uint32_t ObjectHashTableShape::Hash(JSObject* key) {
4504 MaybeObject* maybe_hash = key->GetIdentityHash(JSObject::OMIT_CREATION);
4505 ASSERT(!maybe_hash->IsFailure());
4506 return Smi::cast(maybe_hash->ToObjectUnchecked())->value();
4507}
4508
4509
4510uint32_t ObjectHashTableShape::HashForObject(JSObject* key, Object* other) {
4511 MaybeObject* maybe_hash = JSObject::cast(other)->GetIdentityHash(
4512 JSObject::OMIT_CREATION);
4513 ASSERT(!maybe_hash->IsFailure());
4514 return Smi::cast(maybe_hash->ToObjectUnchecked())->value();
4515}
4516
4517
4518MaybeObject* ObjectHashTableShape::AsObject(JSObject* key) {
4519 return key;
4520}
4521
4522
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004523void ObjectHashTable::RemoveEntry(int entry) {
4524 RemoveEntry(entry, GetHeap());
4525}
4526
4527
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004528void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004529 // No write barrier is needed since empty_fixed_array is not in new space.
4530 // Please note this function is used during marking:
4531 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004532 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4533 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004534}
4535
4536
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004537void JSArray::EnsureSize(int required_size) {
4538 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004539 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004540 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4541 if (elts->length() < required_size) {
4542 // Doubling in size would be overkill, but leave some slack to avoid
4543 // constantly growing.
4544 Expand(required_size + (required_size >> 3));
4545 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004546 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004547 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4548 // Expand will allocate a new backing store in new space even if the size
4549 // we asked for isn't larger than what we had before.
4550 Expand(required_size);
4551 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004552}
4553
4554
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004555void JSArray::set_length(Smi* length) {
4556 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4557}
4558
4559
ager@chromium.org7c537e22008-10-16 08:43:32 +00004560void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004561 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004562 set_elements(storage);
4563}
4564
4565
lrn@chromium.org303ada72010-10-27 09:33:13 +00004566MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004567 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004568 return GetHeap()->CopyFixedArray(this);
4569}
4570
4571
4572Relocatable::Relocatable(Isolate* isolate) {
4573 ASSERT(isolate == Isolate::Current());
4574 isolate_ = isolate;
4575 prev_ = isolate->relocatable_top();
4576 isolate->set_relocatable_top(this);
4577}
4578
4579
4580Relocatable::~Relocatable() {
4581 ASSERT(isolate_ == Isolate::Current());
4582 ASSERT_EQ(isolate_->relocatable_top(), this);
4583 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004584}
4585
4586
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004587int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4588 return map->instance_size();
4589}
4590
4591
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004592void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004593 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004594 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004595}
4596
4597
4598template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004599void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004600 StaticVisitor::VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004601 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004602}
4603
4604
4605void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4606 typedef v8::String::ExternalAsciiStringResource Resource;
4607 v->VisitExternalAsciiString(
4608 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4609}
4610
4611
4612template<typename StaticVisitor>
4613void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4614 typedef v8::String::ExternalAsciiStringResource Resource;
4615 StaticVisitor::VisitExternalAsciiString(
4616 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4617}
4618
4619
4620void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4621 typedef v8::String::ExternalStringResource Resource;
4622 v->VisitExternalTwoByteString(
4623 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4624}
4625
4626
4627template<typename StaticVisitor>
4628void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4629 typedef v8::String::ExternalStringResource Resource;
4630 StaticVisitor::VisitExternalTwoByteString(
4631 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4632}
4633
4634#define SLOT_ADDR(obj, offset) \
4635 reinterpret_cast<Object**>((obj)->address() + offset)
4636
4637template<int start_offset, int end_offset, int size>
4638void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4639 HeapObject* obj,
4640 ObjectVisitor* v) {
4641 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4642}
4643
4644
4645template<int start_offset>
4646void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4647 int object_size,
4648 ObjectVisitor* v) {
4649 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4650}
4651
4652#undef SLOT_ADDR
4653
4654
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004655#undef CAST_ACCESSOR
4656#undef INT_ACCESSORS
4657#undef SMI_ACCESSORS
4658#undef ACCESSORS
4659#undef FIELD_ADDR
4660#undef READ_FIELD
4661#undef WRITE_FIELD
4662#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004663#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004664#undef READ_MEMADDR_FIELD
4665#undef WRITE_MEMADDR_FIELD
4666#undef READ_DOUBLE_FIELD
4667#undef WRITE_DOUBLE_FIELD
4668#undef READ_INT_FIELD
4669#undef WRITE_INT_FIELD
4670#undef READ_SHORT_FIELD
4671#undef WRITE_SHORT_FIELD
4672#undef READ_BYTE_FIELD
4673#undef WRITE_BYTE_FIELD
4674
4675
4676} } // namespace v8::internal
4677
4678#endif // V8_OBJECTS_INL_H_