blob: bb24a2f8544ef73e069031be3bd38c0ed6315855 [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
kasper.lund7276f142008-07-30 08:49:36 +00002884InlineCacheState Code::ic_state() {
2885 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002886 // Only allow uninitialized or debugger states for non-IC code
2887 // objects. This is used in the debugger to determine whether or not
2888 // a call to code object has been replaced with a debug break call.
2889 ASSERT(is_inline_cache_stub() ||
2890 result == UNINITIALIZED ||
2891 result == DEBUG_BREAK ||
2892 result == DEBUG_PREPARE_STEP_IN);
2893 return result;
2894}
2895
2896
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002897Code::ExtraICState Code::extra_ic_state() {
2898 ASSERT(is_inline_cache_stub());
2899 return ExtractExtraICStateFromFlags(flags());
2900}
2901
2902
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002903PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002904 return ExtractTypeFromFlags(flags());
2905}
2906
2907
2908int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002909 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002910 return ExtractArgumentsCountFromFlags(flags());
2911}
2912
2913
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002914int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002915 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002916 kind() == UNARY_OP_IC ||
2917 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002918 kind() == COMPARE_IC ||
2919 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002920 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002921}
2922
2923
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002924void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002925 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002926 kind() == UNARY_OP_IC ||
2927 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002928 kind() == COMPARE_IC ||
2929 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002930 ASSERT(0 <= major && major < 256);
2931 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002932}
2933
2934
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002935bool Code::optimizable() {
2936 ASSERT(kind() == FUNCTION);
2937 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2938}
2939
2940
2941void Code::set_optimizable(bool value) {
2942 ASSERT(kind() == FUNCTION);
2943 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2944}
2945
2946
2947bool Code::has_deoptimization_support() {
2948 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002949 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2950 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002951}
2952
2953
2954void Code::set_has_deoptimization_support(bool value) {
2955 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002956 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2957 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
2958 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
2959}
2960
2961
2962bool Code::has_debug_break_slots() {
2963 ASSERT(kind() == FUNCTION);
2964 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2965 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
2966}
2967
2968
2969void Code::set_has_debug_break_slots(bool value) {
2970 ASSERT(kind() == FUNCTION);
2971 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2972 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
2973 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002974}
2975
2976
2977int Code::allow_osr_at_loop_nesting_level() {
2978 ASSERT(kind() == FUNCTION);
2979 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2980}
2981
2982
2983void Code::set_allow_osr_at_loop_nesting_level(int level) {
2984 ASSERT(kind() == FUNCTION);
2985 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2986 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2987}
2988
2989
2990unsigned Code::stack_slots() {
2991 ASSERT(kind() == OPTIMIZED_FUNCTION);
2992 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2993}
2994
2995
2996void Code::set_stack_slots(unsigned slots) {
2997 ASSERT(kind() == OPTIMIZED_FUNCTION);
2998 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2999}
3000
3001
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003002unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003003 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003004 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003005}
3006
3007
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003008void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003009 ASSERT(kind() == OPTIMIZED_FUNCTION);
3010 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003011 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003012}
3013
3014
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003015unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003016 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003017 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003018}
3019
3020
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003021void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003022 ASSERT(kind() == FUNCTION);
3023 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003024 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003025}
3026
3027
3028CheckType Code::check_type() {
3029 ASSERT(is_call_stub() || is_keyed_call_stub());
3030 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3031 return static_cast<CheckType>(type);
3032}
3033
3034
3035void Code::set_check_type(CheckType value) {
3036 ASSERT(is_call_stub() || is_keyed_call_stub());
3037 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3038}
3039
3040
danno@chromium.org40cb8782011-05-25 07:58:50 +00003041byte Code::unary_op_type() {
3042 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003043 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3044}
3045
3046
danno@chromium.org40cb8782011-05-25 07:58:50 +00003047void Code::set_unary_op_type(byte value) {
3048 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003049 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3050}
3051
3052
danno@chromium.org40cb8782011-05-25 07:58:50 +00003053byte Code::binary_op_type() {
3054 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003055 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3056}
3057
3058
danno@chromium.org40cb8782011-05-25 07:58:50 +00003059void Code::set_binary_op_type(byte value) {
3060 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003061 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3062}
3063
3064
danno@chromium.org40cb8782011-05-25 07:58:50 +00003065byte Code::binary_op_result_type() {
3066 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003067 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3068}
3069
3070
danno@chromium.org40cb8782011-05-25 07:58:50 +00003071void Code::set_binary_op_result_type(byte value) {
3072 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003073 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3074}
3075
3076
3077byte Code::compare_state() {
3078 ASSERT(is_compare_ic_stub());
3079 return READ_BYTE_FIELD(this, kCompareStateOffset);
3080}
3081
3082
3083void Code::set_compare_state(byte value) {
3084 ASSERT(is_compare_ic_stub());
3085 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3086}
3087
3088
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003089byte Code::to_boolean_state() {
3090 ASSERT(is_to_boolean_ic_stub());
3091 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3092}
3093
3094
3095void Code::set_to_boolean_state(byte value) {
3096 ASSERT(is_to_boolean_ic_stub());
3097 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3098}
3099
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003100bool Code::is_inline_cache_stub() {
3101 Kind kind = this->kind();
3102 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3103}
3104
3105
3106Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003107 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003108 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003109 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003110 int argc,
3111 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003112 // Extra IC state is only allowed for call IC stubs or for store IC
3113 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003114 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003115 kind == CALL_IC ||
3116 kind == STORE_IC ||
3117 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003118 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003119 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003120 | ICStateField::encode(ic_state)
3121 | TypeField::encode(type)
3122 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003123 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003124 | CacheHolderField::encode(holder);
3125 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003126}
3127
3128
3129Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3130 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003131 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003132 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003133 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003134 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003135}
3136
3137
3138Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003139 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003140}
3141
3142
kasper.lund7276f142008-07-30 08:49:36 +00003143InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003144 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003145}
3146
3147
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003148Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003149 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003150}
3151
3152
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003153PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003154 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003155}
3156
3157
3158int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003159 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003160}
3161
3162
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003163InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003164 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003165}
3166
3167
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003168Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003169 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003170 return static_cast<Flags>(bits);
3171}
3172
3173
ager@chromium.org8bb60582008-12-11 12:02:20 +00003174Code* Code::GetCodeFromTargetAddress(Address address) {
3175 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3176 // GetCodeFromTargetAddress might be called when marking objects during mark
3177 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3178 // Code::cast. Code::cast does not work when the object's map is
3179 // marked.
3180 Code* result = reinterpret_cast<Code*>(code);
3181 return result;
3182}
3183
3184
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003185Isolate* Map::isolate() {
3186 return heap()->isolate();
3187}
3188
3189
3190Heap* Map::heap() {
3191 // NOTE: address() helper is not used to save one instruction.
3192 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3193 ASSERT(heap != NULL);
3194 ASSERT(heap->isolate() == Isolate::Current());
3195 return heap;
3196}
3197
3198
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003199Heap* Code::heap() {
3200 // NOTE: address() helper is not used to save one instruction.
3201 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3202 ASSERT(heap != NULL);
3203 ASSERT(heap->isolate() == Isolate::Current());
3204 return heap;
3205}
3206
3207
3208Isolate* Code::isolate() {
3209 return heap()->isolate();
3210}
3211
3212
3213Heap* JSGlobalPropertyCell::heap() {
3214 // NOTE: address() helper is not used to save one instruction.
3215 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3216 ASSERT(heap != NULL);
3217 ASSERT(heap->isolate() == Isolate::Current());
3218 return heap;
3219}
3220
3221
3222Isolate* JSGlobalPropertyCell::isolate() {
3223 return heap()->isolate();
3224}
3225
3226
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003227Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3228 return HeapObject::
3229 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3230}
3231
3232
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003233Object* Map::prototype() {
3234 return READ_FIELD(this, kPrototypeOffset);
3235}
3236
3237
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003238void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003239 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003240 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003241 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003242}
3243
3244
lrn@chromium.org303ada72010-10-27 09:33:13 +00003245MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003246 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003247 Object* obj;
3248 { MaybeObject* maybe_obj = CopyDropTransitions();
3249 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3250 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003251 Map* new_map = Map::cast(obj);
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003252 new_map->set_elements_kind(FAST_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003253 isolate()->counters()->map_to_fast_elements()->Increment();
3254 return new_map;
3255}
3256
3257
3258MaybeObject* Map::GetFastDoubleElementsMap() {
3259 if (has_fast_double_elements()) return this;
3260 Object* obj;
3261 { MaybeObject* maybe_obj = CopyDropTransitions();
3262 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3263 }
3264 Map* new_map = Map::cast(obj);
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003265 new_map->set_elements_kind(FAST_DOUBLE_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003266 isolate()->counters()->map_to_fast_double_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003267 return new_map;
3268}
3269
3270
lrn@chromium.org303ada72010-10-27 09:33:13 +00003271MaybeObject* Map::GetSlowElementsMap() {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003272 if (!has_fast_elements() && !has_fast_double_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003273 Object* obj;
3274 { MaybeObject* maybe_obj = CopyDropTransitions();
3275 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3276 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003277 Map* new_map = Map::cast(obj);
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003278 new_map->set_elements_kind(DICTIONARY_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003279 isolate()->counters()->map_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003280 return new_map;
3281}
3282
3283
danno@chromium.org40cb8782011-05-25 07:58:50 +00003284DescriptorArray* Map::instance_descriptors() {
3285 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3286 if (object->IsSmi()) {
3287 return HEAP->empty_descriptor_array();
3288 } else {
3289 return DescriptorArray::cast(object);
3290 }
3291}
3292
3293
3294void Map::init_instance_descriptors() {
3295 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3296}
3297
3298
3299void Map::clear_instance_descriptors() {
3300 Object* object = READ_FIELD(this,
3301 kInstanceDescriptorsOrBitField3Offset);
3302 if (!object->IsSmi()) {
3303 WRITE_FIELD(
3304 this,
3305 kInstanceDescriptorsOrBitField3Offset,
3306 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3307 }
3308}
3309
3310
3311void Map::set_instance_descriptors(DescriptorArray* value,
3312 WriteBarrierMode mode) {
3313 Object* object = READ_FIELD(this,
3314 kInstanceDescriptorsOrBitField3Offset);
3315 if (value == isolate()->heap()->empty_descriptor_array()) {
3316 clear_instance_descriptors();
3317 return;
3318 } else {
3319 if (object->IsSmi()) {
3320 value->set_bit_field3_storage(Smi::cast(object)->value());
3321 } else {
3322 value->set_bit_field3_storage(
3323 DescriptorArray::cast(object)->bit_field3_storage());
3324 }
3325 }
3326 ASSERT(!is_shared());
3327 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
3328 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3329 this,
3330 kInstanceDescriptorsOrBitField3Offset,
3331 mode);
3332}
3333
3334
3335int Map::bit_field3() {
3336 Object* object = READ_FIELD(this,
3337 kInstanceDescriptorsOrBitField3Offset);
3338 if (object->IsSmi()) {
3339 return Smi::cast(object)->value();
3340 } else {
3341 return DescriptorArray::cast(object)->bit_field3_storage();
3342 }
3343}
3344
3345
3346void Map::set_bit_field3(int value) {
3347 ASSERT(Smi::IsValid(value));
3348 Object* object = READ_FIELD(this,
3349 kInstanceDescriptorsOrBitField3Offset);
3350 if (object->IsSmi()) {
3351 WRITE_FIELD(this,
3352 kInstanceDescriptorsOrBitField3Offset,
3353 Smi::FromInt(value));
3354 } else {
3355 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3356 }
3357}
3358
3359
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003360ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003361ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003362ACCESSORS(Map, constructor, Object, kConstructorOffset)
3363
3364ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
3365ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003366ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
3367 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003368
3369ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3370ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003371ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003372
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003373ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003374
3375ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3376ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3377ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3378ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3379ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3380
3381ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3382ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3383ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3384
3385ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3386ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3387ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3388ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3389ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3390ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3391
3392ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3393ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3394
3395ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3396ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3397
3398ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3399ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003400ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3401 kPropertyAccessorsOffset)
3402ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3403 kPrototypeTemplateOffset)
3404ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3405ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3406 kNamedPropertyHandlerOffset)
3407ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3408 kIndexedPropertyHandlerOffset)
3409ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3410 kInstanceTemplateOffset)
3411ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3412ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003413ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3414 kInstanceCallHandlerOffset)
3415ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3416 kAccessCheckInfoOffset)
3417ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3418
3419ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003420ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3421 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003422
3423ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3424ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3425
3426ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3427
3428ACCESSORS(Script, source, Object, kSourceOffset)
3429ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003430ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003431ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3432ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003433ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003434ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003435ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003436ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003437ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003438ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003439ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003440ACCESSORS(Script, eval_from_instructions_offset, Smi,
3441 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003442
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003443#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003444ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3445ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3446ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3447ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3448
3449ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3450ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3451ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3452ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003453#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003454
3455ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003456ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3457ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003458ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3459 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003460ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003461ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3462ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003463ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003464ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3465 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003466
3467BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3468 kHiddenPrototypeBit)
3469BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3470BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3471 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003472BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3473 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003474BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3475 kIsExpressionBit)
3476BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3477 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003478BOOL_GETTER(SharedFunctionInfo,
3479 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003480 has_only_simple_this_property_assignments,
3481 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003482BOOL_ACCESSORS(SharedFunctionInfo,
3483 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003484 allows_lazy_compilation,
3485 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003486BOOL_ACCESSORS(SharedFunctionInfo,
3487 compiler_hints,
3488 uses_arguments,
3489 kUsesArguments)
3490BOOL_ACCESSORS(SharedFunctionInfo,
3491 compiler_hints,
3492 has_duplicate_parameters,
3493 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003494
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003495
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003496#if V8_HOST_ARCH_32_BIT
3497SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3498SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003499 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003500SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003501 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003502SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3503SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003504 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003505SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3506SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003507 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003508SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003509 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003510SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003511 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003512SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003513#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003514
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003515#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003516 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003517 int holder::name() { \
3518 int value = READ_INT_FIELD(this, offset); \
3519 ASSERT(kHeapObjectTag == 1); \
3520 ASSERT((value & kHeapObjectTag) == 0); \
3521 return value >> 1; \
3522 } \
3523 void holder::set_##name(int value) { \
3524 ASSERT(kHeapObjectTag == 1); \
3525 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3526 (value & 0xC0000000) == 0x000000000); \
3527 WRITE_INT_FIELD(this, \
3528 offset, \
3529 (value << 1) & ~kHeapObjectTag); \
3530 }
3531
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003532#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3533 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003534 INT_ACCESSORS(holder, name, offset)
3535
3536
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003537PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003538PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3539 formal_parameter_count,
3540 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003541
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003542PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3543 expected_nof_properties,
3544 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003545PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3546
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003547PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3548PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3549 start_position_and_type,
3550 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003551
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003552PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3553 function_token_position,
3554 kFunctionTokenPositionOffset)
3555PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3556 compiler_hints,
3557 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003558
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003559PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3560 this_property_assignments_count,
3561 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003562PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003563#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003564
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003565
3566int SharedFunctionInfo::construction_count() {
3567 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3568}
3569
3570
3571void SharedFunctionInfo::set_construction_count(int value) {
3572 ASSERT(0 <= value && value < 256);
3573 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3574}
3575
3576
whesse@chromium.org7b260152011-06-20 15:33:18 +00003577BOOL_ACCESSORS(SharedFunctionInfo,
3578 compiler_hints,
3579 live_objects_may_exist,
3580 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003581
3582
3583bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003584 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003585}
3586
3587
whesse@chromium.org7b260152011-06-20 15:33:18 +00003588BOOL_GETTER(SharedFunctionInfo,
3589 compiler_hints,
3590 optimization_disabled,
3591 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003592
3593
3594void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3595 set_compiler_hints(BooleanBit::set(compiler_hints(),
3596 kOptimizationDisabled,
3597 disable));
3598 // If disabling optimizations we reflect that in the code object so
3599 // it will not be counted as optimizable code.
3600 if ((code()->kind() == Code::FUNCTION) && disable) {
3601 code()->set_optimizable(false);
3602 }
3603}
3604
3605
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003606BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, strict_mode,
whesse@chromium.org7b260152011-06-20 15:33:18 +00003607 kStrictModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003608BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3609BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3610 name_should_print_as_anonymous,
3611 kNameShouldPrintAsAnonymous)
3612BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3613BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003614
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003615ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3616ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3617
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003618ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3619
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003620bool Script::HasValidSource() {
3621 Object* src = this->source();
3622 if (!src->IsString()) return true;
3623 String* src_str = String::cast(src);
3624 if (!StringShape(src_str).IsExternal()) return true;
3625 if (src_str->IsAsciiRepresentation()) {
3626 return ExternalAsciiString::cast(src)->resource() != NULL;
3627 } else if (src_str->IsTwoByteRepresentation()) {
3628 return ExternalTwoByteString::cast(src)->resource() != NULL;
3629 }
3630 return true;
3631}
3632
3633
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003634void SharedFunctionInfo::DontAdaptArguments() {
3635 ASSERT(code()->kind() == Code::BUILTIN);
3636 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3637}
3638
3639
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003640int SharedFunctionInfo::start_position() {
3641 return start_position_and_type() >> kStartPositionShift;
3642}
3643
3644
3645void SharedFunctionInfo::set_start_position(int start_position) {
3646 set_start_position_and_type((start_position << kStartPositionShift)
3647 | (start_position_and_type() & ~kStartPositionMask));
3648}
3649
3650
3651Code* SharedFunctionInfo::code() {
3652 return Code::cast(READ_FIELD(this, kCodeOffset));
3653}
3654
3655
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003656Code* SharedFunctionInfo::unchecked_code() {
3657 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3658}
3659
3660
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003661void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003662 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003663 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003664}
3665
3666
ager@chromium.orgb5737492010-07-15 09:29:43 +00003667SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3668 return reinterpret_cast<SerializedScopeInfo*>(
3669 READ_FIELD(this, kScopeInfoOffset));
3670}
3671
3672
3673void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3674 WriteBarrierMode mode) {
3675 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003676 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003677}
3678
3679
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003680Smi* SharedFunctionInfo::deopt_counter() {
3681 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3682}
3683
3684
3685void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3686 WRITE_FIELD(this, kDeoptCounterOffset, value);
3687}
3688
3689
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003690bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003691 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003692 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003693}
3694
3695
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003696bool SharedFunctionInfo::IsApiFunction() {
3697 return function_data()->IsFunctionTemplateInfo();
3698}
3699
3700
3701FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3702 ASSERT(IsApiFunction());
3703 return FunctionTemplateInfo::cast(function_data());
3704}
3705
3706
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003707bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003708 return function_data()->IsSmi();
3709}
3710
3711
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003712BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3713 ASSERT(HasBuiltinFunctionId());
3714 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003715}
3716
3717
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003718int SharedFunctionInfo::code_age() {
3719 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3720}
3721
3722
3723void SharedFunctionInfo::set_code_age(int code_age) {
3724 set_compiler_hints(compiler_hints() |
3725 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3726}
3727
3728
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003729bool SharedFunctionInfo::has_deoptimization_support() {
3730 Code* code = this->code();
3731 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3732}
3733
3734
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003735bool JSFunction::IsBuiltin() {
3736 return context()->global()->IsJSBuiltinsObject();
3737}
3738
3739
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003740bool JSFunction::NeedsArgumentsAdaption() {
3741 return shared()->formal_parameter_count() !=
3742 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3743}
3744
3745
3746bool JSFunction::IsOptimized() {
3747 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3748}
3749
3750
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003751bool JSFunction::IsOptimizable() {
3752 return code()->kind() == Code::FUNCTION && code()->optimizable();
3753}
3754
3755
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003756bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003757 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003758}
3759
3760
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003761Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003762 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003763}
3764
3765
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003766Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003767 return reinterpret_cast<Code*>(
3768 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003769}
3770
3771
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003772void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003773 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003774 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003775 Address entry = value->entry();
3776 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003777}
3778
3779
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003780void JSFunction::ReplaceCode(Code* code) {
3781 bool was_optimized = IsOptimized();
3782 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3783
3784 set_code(code);
3785
3786 // Add/remove the function from the list of optimized functions for this
3787 // context based on the state change.
3788 if (!was_optimized && is_optimized) {
3789 context()->global_context()->AddOptimizedFunction(this);
3790 }
3791 if (was_optimized && !is_optimized) {
3792 context()->global_context()->RemoveOptimizedFunction(this);
3793 }
3794}
3795
3796
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003797Context* JSFunction::context() {
3798 return Context::cast(READ_FIELD(this, kContextOffset));
3799}
3800
3801
3802Object* JSFunction::unchecked_context() {
3803 return READ_FIELD(this, kContextOffset);
3804}
3805
3806
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003807SharedFunctionInfo* JSFunction::unchecked_shared() {
3808 return reinterpret_cast<SharedFunctionInfo*>(
3809 READ_FIELD(this, kSharedFunctionInfoOffset));
3810}
3811
3812
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003813void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003814 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003815 WRITE_FIELD(this, kContextOffset, value);
3816 WRITE_BARRIER(this, kContextOffset);
3817}
3818
3819ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3820 kPrototypeOrInitialMapOffset)
3821
3822
3823Map* JSFunction::initial_map() {
3824 return Map::cast(prototype_or_initial_map());
3825}
3826
3827
3828void JSFunction::set_initial_map(Map* value) {
3829 set_prototype_or_initial_map(value);
3830}
3831
3832
3833bool JSFunction::has_initial_map() {
3834 return prototype_or_initial_map()->IsMap();
3835}
3836
3837
3838bool JSFunction::has_instance_prototype() {
3839 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3840}
3841
3842
3843bool JSFunction::has_prototype() {
3844 return map()->has_non_instance_prototype() || has_instance_prototype();
3845}
3846
3847
3848Object* JSFunction::instance_prototype() {
3849 ASSERT(has_instance_prototype());
3850 if (has_initial_map()) return initial_map()->prototype();
3851 // When there is no initial map and the prototype is a JSObject, the
3852 // initial map field is used for the prototype field.
3853 return prototype_or_initial_map();
3854}
3855
3856
3857Object* JSFunction::prototype() {
3858 ASSERT(has_prototype());
3859 // If the function's prototype property has been set to a non-JSObject
3860 // value, that value is stored in the constructor field of the map.
3861 if (map()->has_non_instance_prototype()) return map()->constructor();
3862 return instance_prototype();
3863}
3864
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003865bool JSFunction::should_have_prototype() {
3866 return map()->function_with_prototype();
3867}
3868
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003869
3870bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003871 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003872}
3873
3874
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003875int JSFunction::NumberOfLiterals() {
3876 return literals()->length();
3877}
3878
3879
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003880Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003881 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003882 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003883}
3884
3885
3886void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3887 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003888 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003889 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3890 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3891}
3892
3893
3894Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003895 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003896 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3897}
3898
3899
3900void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3901 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003902 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003903 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003904 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003905}
3906
3907
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003908ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003909ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
3910ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
3911
3912
3913void JSProxy::InitializeBody(int object_size, Object* value) {
3914 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
3915 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
3916 WRITE_FIELD(this, offset, value);
3917 }
3918}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003919
3920
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003921ACCESSORS(JSWeakMap, table, ObjectHashTable, kTableOffset)
3922ACCESSORS_GCSAFE(JSWeakMap, next, Object, kNextOffset)
3923
3924
3925ObjectHashTable* JSWeakMap::unchecked_table() {
3926 return reinterpret_cast<ObjectHashTable*>(READ_FIELD(this, kTableOffset));
3927}
3928
3929
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003930Address Foreign::address() {
3931 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003932}
3933
3934
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003935void Foreign::set_address(Address value) {
3936 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003937}
3938
3939
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003940ACCESSORS(JSValue, value, Object, kValueOffset)
3941
3942
3943JSValue* JSValue::cast(Object* obj) {
3944 ASSERT(obj->IsJSValue());
3945 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3946 return reinterpret_cast<JSValue*>(obj);
3947}
3948
3949
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003950ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3951ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3952ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3953ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3954ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3955SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3956SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3957
3958
3959JSMessageObject* JSMessageObject::cast(Object* obj) {
3960 ASSERT(obj->IsJSMessageObject());
3961 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3962 return reinterpret_cast<JSMessageObject*>(obj);
3963}
3964
3965
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003966INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003967ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003968ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003969ACCESSORS(Code, next_code_flushing_candidate,
3970 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003971
3972
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003973byte* Code::instruction_start() {
3974 return FIELD_ADDR(this, kHeaderSize);
3975}
3976
3977
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003978byte* Code::instruction_end() {
3979 return instruction_start() + instruction_size();
3980}
3981
3982
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003983int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003984 return RoundUp(instruction_size(), kObjectAlignment);
3985}
3986
3987
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003988FixedArray* Code::unchecked_deoptimization_data() {
3989 return reinterpret_cast<FixedArray*>(
3990 READ_FIELD(this, kDeoptimizationDataOffset));
3991}
3992
3993
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003994ByteArray* Code::unchecked_relocation_info() {
3995 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003996}
3997
3998
3999byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004000 return unchecked_relocation_info()->GetDataStartAddress();
4001}
4002
4003
4004int Code::relocation_size() {
4005 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004006}
4007
4008
4009byte* Code::entry() {
4010 return instruction_start();
4011}
4012
4013
4014bool Code::contains(byte* pc) {
4015 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00004016 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004017}
4018
4019
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004020ACCESSORS(JSArray, length, Object, kLengthOffset)
4021
4022
ager@chromium.org236ad962008-09-25 09:45:57 +00004023ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004024
4025
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004026JSRegExp::Type JSRegExp::TypeTag() {
4027 Object* data = this->data();
4028 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4029 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4030 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004031}
4032
4033
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004034JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4035 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4036 return static_cast<JSRegExp::Type>(smi->value());
4037}
4038
4039
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004040int JSRegExp::CaptureCount() {
4041 switch (TypeTag()) {
4042 case ATOM:
4043 return 0;
4044 case IRREGEXP:
4045 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4046 default:
4047 UNREACHABLE();
4048 return -1;
4049 }
4050}
4051
4052
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004053JSRegExp::Flags JSRegExp::GetFlags() {
4054 ASSERT(this->data()->IsFixedArray());
4055 Object* data = this->data();
4056 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4057 return Flags(smi->value());
4058}
4059
4060
4061String* JSRegExp::Pattern() {
4062 ASSERT(this->data()->IsFixedArray());
4063 Object* data = this->data();
4064 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4065 return pattern;
4066}
4067
4068
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004069Object* JSRegExp::DataAt(int index) {
4070 ASSERT(TypeTag() != NOT_COMPILED);
4071 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004072}
4073
4074
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004075Object* JSRegExp::DataAtUnchecked(int index) {
4076 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4077 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4078 return READ_FIELD(fa, offset);
4079}
4080
4081
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004082void JSRegExp::SetDataAt(int index, Object* value) {
4083 ASSERT(TypeTag() != NOT_COMPILED);
4084 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4085 FixedArray::cast(data())->set(index, value);
4086}
4087
4088
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004089void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4090 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4091 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4092 if (value->IsSmi()) {
4093 fa->set_unchecked(index, Smi::cast(value));
4094 } else {
4095 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4096 }
4097}
4098
4099
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004100ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004101 ElementsKind kind = map()->elements_kind();
4102 ASSERT((kind == FAST_ELEMENTS &&
4103 (elements()->map() == GetHeap()->fixed_array_map() ||
4104 elements()->map() == GetHeap()->fixed_cow_array_map())) ||
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004105 (kind == FAST_DOUBLE_ELEMENTS &&
4106 elements()->IsFixedDoubleArray()) ||
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004107 (kind == DICTIONARY_ELEMENTS &&
4108 elements()->IsFixedArray() &&
4109 elements()->IsDictionary()) ||
4110 (kind > DICTIONARY_ELEMENTS));
4111 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004112}
4113
4114
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004115ElementsAccessor* JSObject::GetElementsAccessor() {
4116 return ElementsAccessor::ForKind(GetElementsKind());
4117}
4118
4119
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004120bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004121 return GetElementsKind() == FAST_ELEMENTS;
4122}
4123
4124
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004125bool JSObject::HasFastDoubleElements() {
4126 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4127}
4128
4129
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004130bool JSObject::HasDictionaryElements() {
4131 return GetElementsKind() == DICTIONARY_ELEMENTS;
4132}
4133
4134
ager@chromium.org3811b432009-10-28 14:53:37 +00004135bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004136 HeapObject* array = elements();
4137 ASSERT(array != NULL);
4138 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004139}
4140
4141
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004142#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4143bool JSObject::HasExternal##name##Elements() { \
4144 HeapObject* array = elements(); \
4145 ASSERT(array != NULL); \
4146 if (!array->IsHeapObject()) \
4147 return false; \
4148 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004149}
4150
4151
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004152EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4153EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4154EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4155EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4156 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4157EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4158EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4159 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4160EXTERNAL_ELEMENTS_CHECK(Float,
4161 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004162EXTERNAL_ELEMENTS_CHECK(Double,
4163 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004164EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004165
4166
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004167bool JSObject::HasNamedInterceptor() {
4168 return map()->has_named_interceptor();
4169}
4170
4171
4172bool JSObject::HasIndexedInterceptor() {
4173 return map()->has_indexed_interceptor();
4174}
4175
4176
ager@chromium.org5c838252010-02-19 08:53:10 +00004177bool JSObject::AllowsSetElementsLength() {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004178 bool result = elements()->IsFixedArray() ||
4179 elements()->IsFixedDoubleArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004180 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00004181 return result;
4182}
4183
4184
lrn@chromium.org303ada72010-10-27 09:33:13 +00004185MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004186 ASSERT(HasFastElements());
4187 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004188 Isolate* isolate = GetIsolate();
4189 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004190 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004191 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4192 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004193 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4194 return maybe_writable_elems;
4195 }
4196 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004197 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004198 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004199 return writable_elems;
4200}
4201
4202
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004203StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004204 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004205 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004206}
4207
4208
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004209NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004210 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004211 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004212}
4213
4214
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004215bool String::IsHashFieldComputed(uint32_t field) {
4216 return (field & kHashNotComputedMask) == 0;
4217}
4218
4219
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004220bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004221 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004222}
4223
4224
4225uint32_t String::Hash() {
4226 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004227 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004228 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004229 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004230 return ComputeAndSetHash();
4231}
4232
4233
ager@chromium.org7c537e22008-10-16 08:43:32 +00004234StringHasher::StringHasher(int length)
4235 : length_(length),
4236 raw_running_hash_(0),
4237 array_index_(0),
4238 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4239 is_first_char_(true),
4240 is_valid_(true) { }
4241
4242
4243bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004244 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004245}
4246
4247
4248void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004249 // Use the Jenkins one-at-a-time hash function to update the hash
4250 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004251 raw_running_hash_ += c;
4252 raw_running_hash_ += (raw_running_hash_ << 10);
4253 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004254 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004255 if (is_array_index_) {
4256 if (c < '0' || c > '9') {
4257 is_array_index_ = false;
4258 } else {
4259 int d = c - '0';
4260 if (is_first_char_) {
4261 is_first_char_ = false;
4262 if (c == '0' && length_ > 1) {
4263 is_array_index_ = false;
4264 return;
4265 }
4266 }
4267 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4268 is_array_index_ = false;
4269 } else {
4270 array_index_ = array_index_ * 10 + d;
4271 }
4272 }
4273 }
4274}
4275
4276
4277void StringHasher::AddCharacterNoIndex(uc32 c) {
4278 ASSERT(!is_array_index());
4279 raw_running_hash_ += c;
4280 raw_running_hash_ += (raw_running_hash_ << 10);
4281 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4282}
4283
4284
4285uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004286 // Get the calculated raw hash value and do some more bit ops to distribute
4287 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004288 uint32_t result = raw_running_hash_;
4289 result += (result << 3);
4290 result ^= (result >> 11);
4291 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004292 if (result == 0) {
4293 result = 27;
4294 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004295 return result;
4296}
4297
4298
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004299template <typename schar>
4300uint32_t HashSequentialString(const schar* chars, int length) {
4301 StringHasher hasher(length);
4302 if (!hasher.has_trivial_hash()) {
4303 int i;
4304 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4305 hasher.AddCharacter(chars[i]);
4306 }
4307 for (; i < length; i++) {
4308 hasher.AddCharacterNoIndex(chars[i]);
4309 }
4310 }
4311 return hasher.GetHashField();
4312}
4313
4314
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004315bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004316 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004317 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4318 return false;
4319 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004320 return SlowAsArrayIndex(index);
4321}
4322
4323
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004324Object* JSReceiver::GetPrototype() {
4325 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004326}
4327
4328
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004329bool JSReceiver::HasProperty(String* name) {
4330 if (IsJSProxy()) {
4331 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4332 }
4333 return GetPropertyAttribute(name) != ABSENT;
4334}
4335
4336
4337bool JSReceiver::HasLocalProperty(String* name) {
4338 if (IsJSProxy()) {
4339 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4340 }
4341 return GetLocalPropertyAttribute(name) != ABSENT;
4342}
4343
4344
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004345PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004346 return GetPropertyAttributeWithReceiver(this, key);
4347}
4348
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004349// TODO(504): this may be useful in other places too where JSGlobalProxy
4350// is used.
4351Object* JSObject::BypassGlobalProxy() {
4352 if (IsJSGlobalProxy()) {
4353 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004354 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004355 ASSERT(proto->IsJSGlobalObject());
4356 return proto;
4357 }
4358 return this;
4359}
4360
4361
4362bool JSObject::HasHiddenPropertiesObject() {
4363 ASSERT(!IsJSGlobalProxy());
4364 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004365 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004366 false) != ABSENT;
4367}
4368
4369
4370Object* JSObject::GetHiddenPropertiesObject() {
4371 ASSERT(!IsJSGlobalProxy());
4372 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004373 // You can't install a getter on a property indexed by the hidden symbol,
4374 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
4375 // object.
4376 Object* result =
4377 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004378 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00004379 &attributes)->ToObjectUnchecked();
4380 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004381}
4382
4383
lrn@chromium.org303ada72010-10-27 09:33:13 +00004384MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004385 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004386 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004387 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00004388 DONT_ENUM,
4389 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004390}
4391
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004392
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004393bool JSObject::HasHiddenProperties() {
4394 return !GetHiddenProperties(OMIT_CREATION)->ToObjectChecked()->IsUndefined();
4395}
4396
4397
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004398bool JSObject::HasElement(uint32_t index) {
4399 return HasElementWithReceiver(this, index);
4400}
4401
4402
4403bool AccessorInfo::all_can_read() {
4404 return BooleanBit::get(flag(), kAllCanReadBit);
4405}
4406
4407
4408void AccessorInfo::set_all_can_read(bool value) {
4409 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4410}
4411
4412
4413bool AccessorInfo::all_can_write() {
4414 return BooleanBit::get(flag(), kAllCanWriteBit);
4415}
4416
4417
4418void AccessorInfo::set_all_can_write(bool value) {
4419 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4420}
4421
4422
ager@chromium.org870a0b62008-11-04 11:43:05 +00004423bool AccessorInfo::prohibits_overwriting() {
4424 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4425}
4426
4427
4428void AccessorInfo::set_prohibits_overwriting(bool value) {
4429 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4430}
4431
4432
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004433PropertyAttributes AccessorInfo::property_attributes() {
4434 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4435}
4436
4437
4438void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004439 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004440}
4441
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004442
4443template<typename Shape, typename Key>
4444void Dictionary<Shape, Key>::SetEntry(int entry,
4445 Object* key,
4446 Object* value) {
4447 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4448}
4449
4450
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004451template<typename Shape, typename Key>
4452void Dictionary<Shape, Key>::SetEntry(int entry,
4453 Object* key,
4454 Object* value,
4455 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004456 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004457 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004458 AssertNoAllocation no_gc;
4459 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004460 FixedArray::set(index, key, mode);
4461 FixedArray::set(index+1, value, mode);
4462 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004463}
4464
4465
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004466bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4467 ASSERT(other->IsNumber());
4468 return key == static_cast<uint32_t>(other->Number());
4469}
4470
4471
4472uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4473 return ComputeIntegerHash(key);
4474}
4475
4476
4477uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4478 ASSERT(other->IsNumber());
4479 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4480}
4481
4482
4483MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4484 return Isolate::Current()->heap()->NumberFromUint32(key);
4485}
4486
4487
4488bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4489 // We know that all entries in a hash table had their hash keys created.
4490 // Use that knowledge to have fast failure.
4491 if (key->Hash() != String::cast(other)->Hash()) return false;
4492 return key->Equals(String::cast(other));
4493}
4494
4495
4496uint32_t StringDictionaryShape::Hash(String* key) {
4497 return key->Hash();
4498}
4499
4500
4501uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4502 return String::cast(other)->Hash();
4503}
4504
4505
4506MaybeObject* StringDictionaryShape::AsObject(String* key) {
4507 return key;
4508}
4509
4510
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004511bool ObjectHashTableShape::IsMatch(JSObject* key, Object* other) {
4512 return key == JSObject::cast(other);
4513}
4514
4515
4516uint32_t ObjectHashTableShape::Hash(JSObject* key) {
4517 MaybeObject* maybe_hash = key->GetIdentityHash(JSObject::OMIT_CREATION);
4518 ASSERT(!maybe_hash->IsFailure());
4519 return Smi::cast(maybe_hash->ToObjectUnchecked())->value();
4520}
4521
4522
4523uint32_t ObjectHashTableShape::HashForObject(JSObject* key, Object* other) {
4524 MaybeObject* maybe_hash = JSObject::cast(other)->GetIdentityHash(
4525 JSObject::OMIT_CREATION);
4526 ASSERT(!maybe_hash->IsFailure());
4527 return Smi::cast(maybe_hash->ToObjectUnchecked())->value();
4528}
4529
4530
4531MaybeObject* ObjectHashTableShape::AsObject(JSObject* key) {
4532 return key;
4533}
4534
4535
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004536void ObjectHashTable::RemoveEntry(int entry) {
4537 RemoveEntry(entry, GetHeap());
4538}
4539
4540
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004541void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004542 // No write barrier is needed since empty_fixed_array is not in new space.
4543 // Please note this function is used during marking:
4544 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004545 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4546 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004547}
4548
4549
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004550void JSArray::EnsureSize(int required_size) {
4551 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004552 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004553 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4554 if (elts->length() < required_size) {
4555 // Doubling in size would be overkill, but leave some slack to avoid
4556 // constantly growing.
4557 Expand(required_size + (required_size >> 3));
4558 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004559 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004560 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4561 // Expand will allocate a new backing store in new space even if the size
4562 // we asked for isn't larger than what we had before.
4563 Expand(required_size);
4564 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004565}
4566
4567
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004568void JSArray::set_length(Smi* length) {
4569 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4570}
4571
4572
ager@chromium.org7c537e22008-10-16 08:43:32 +00004573void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004574 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004575 set_elements(storage);
4576}
4577
4578
lrn@chromium.org303ada72010-10-27 09:33:13 +00004579MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004580 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004581 return GetHeap()->CopyFixedArray(this);
4582}
4583
4584
4585Relocatable::Relocatable(Isolate* isolate) {
4586 ASSERT(isolate == Isolate::Current());
4587 isolate_ = isolate;
4588 prev_ = isolate->relocatable_top();
4589 isolate->set_relocatable_top(this);
4590}
4591
4592
4593Relocatable::~Relocatable() {
4594 ASSERT(isolate_ == Isolate::Current());
4595 ASSERT_EQ(isolate_->relocatable_top(), this);
4596 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004597}
4598
4599
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004600int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4601 return map->instance_size();
4602}
4603
4604
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004605void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004606 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004607 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004608}
4609
4610
4611template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004612void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004613 StaticVisitor::VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004614 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004615}
4616
4617
4618void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4619 typedef v8::String::ExternalAsciiStringResource Resource;
4620 v->VisitExternalAsciiString(
4621 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4622}
4623
4624
4625template<typename StaticVisitor>
4626void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4627 typedef v8::String::ExternalAsciiStringResource Resource;
4628 StaticVisitor::VisitExternalAsciiString(
4629 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4630}
4631
4632
4633void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4634 typedef v8::String::ExternalStringResource Resource;
4635 v->VisitExternalTwoByteString(
4636 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4637}
4638
4639
4640template<typename StaticVisitor>
4641void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4642 typedef v8::String::ExternalStringResource Resource;
4643 StaticVisitor::VisitExternalTwoByteString(
4644 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4645}
4646
4647#define SLOT_ADDR(obj, offset) \
4648 reinterpret_cast<Object**>((obj)->address() + offset)
4649
4650template<int start_offset, int end_offset, int size>
4651void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4652 HeapObject* obj,
4653 ObjectVisitor* v) {
4654 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4655}
4656
4657
4658template<int start_offset>
4659void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4660 int object_size,
4661 ObjectVisitor* v) {
4662 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4663}
4664
4665#undef SLOT_ADDR
4666
4667
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004668#undef CAST_ACCESSOR
4669#undef INT_ACCESSORS
4670#undef SMI_ACCESSORS
4671#undef ACCESSORS
4672#undef FIELD_ADDR
4673#undef READ_FIELD
4674#undef WRITE_FIELD
4675#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004676#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004677#undef READ_MEMADDR_FIELD
4678#undef WRITE_MEMADDR_FIELD
4679#undef READ_DOUBLE_FIELD
4680#undef WRITE_DOUBLE_FIELD
4681#undef READ_INT_FIELD
4682#undef WRITE_INT_FIELD
4683#undef READ_SHORT_FIELD
4684#undef WRITE_SHORT_FIELD
4685#undef READ_BYTE_FIELD
4686#undef WRITE_BYTE_FIELD
4687
4688
4689} } // namespace v8::internal
4690
4691#endif // V8_OBJECTS_INL_H_