blob: b4c6a3a03e1efb81ccd3d0bfd5a95d6ba97715e5 [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.
174 ASSERT(kSymbolTag != 0);
175 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());
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000259 ASSERT(kSymbolTag != 0);
260 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());
1752 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1753 FIELD_ADDR(from, kHeaderSize),
1754 old_length * kDoubleSize);
1755 int offset = kHeaderSize + old_length * kDoubleSize;
1756 for (int current = from->length(); current < length(); ++current) {
1757 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1758 offset += kDoubleSize;
1759 }
1760}
1761
1762
1763void FixedDoubleArray::Initialize(FixedArray* from) {
1764 int old_length = from->length();
1765 ASSERT(old_length < length());
1766 for (int i = 0; i < old_length; i++) {
1767 Object* hole_or_object = from->get(i);
1768 if (hole_or_object->IsTheHole()) {
1769 set_the_hole(i);
1770 } else {
1771 set(i, hole_or_object->Number());
1772 }
1773 }
1774 int offset = kHeaderSize + old_length * kDoubleSize;
1775 for (int current = from->length(); current < length(); ++current) {
1776 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1777 offset += kDoubleSize;
1778 }
1779}
1780
1781
1782void FixedDoubleArray::Initialize(NumberDictionary* from) {
1783 int offset = kHeaderSize;
1784 for (int current = 0; current < length(); ++current) {
1785 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1786 offset += kDoubleSize;
1787 }
1788 for (int i = 0; i < from->Capacity(); i++) {
1789 Object* key = from->KeyAt(i);
1790 if (key->IsNumber()) {
1791 uint32_t entry = static_cast<uint32_t>(key->Number());
1792 set(entry, from->ValueAt(i)->Number());
1793 }
1794 }
1795}
1796
1797
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001798WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001799 if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001800 return UPDATE_WRITE_BARRIER;
1801}
1802
1803
1804void FixedArray::set(int index,
1805 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001806 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001807 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001808 ASSERT(index >= 0 && index < this->length());
1809 int offset = kHeaderSize + index * kPointerSize;
1810 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001811 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001812}
1813
1814
1815void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001816 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001817 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001818 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001819 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1820}
1821
1822
1823void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001824 ASSERT(map() != HEAP->fixed_cow_array_map());
1825 set_undefined(GetHeap(), index);
1826}
1827
1828
1829void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001830 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001831 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001832 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001833 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001834}
1835
1836
ager@chromium.org236ad962008-09-25 09:45:57 +00001837void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001838 set_null(GetHeap(), index);
1839}
1840
1841
1842void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001843 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001844 ASSERT(!heap->InNewSpace(heap->null_value()));
1845 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001846}
1847
1848
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001849void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001850 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001851 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001852 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1853 WRITE_FIELD(this,
1854 kHeaderSize + index * kPointerSize,
1855 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001856}
1857
1858
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001859void FixedArray::set_unchecked(int index, Smi* value) {
1860 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1861 int offset = kHeaderSize + index * kPointerSize;
1862 WRITE_FIELD(this, offset, value);
1863}
1864
1865
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001866void FixedArray::set_unchecked(Heap* heap,
1867 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001868 Object* value,
1869 WriteBarrierMode mode) {
1870 int offset = kHeaderSize + index * kPointerSize;
1871 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001872 CONDITIONAL_WRITE_BARRIER(heap, this, offset, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001873}
1874
1875
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001876void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001877 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001878 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1879 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001880}
1881
1882
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001883Object** FixedArray::data_start() {
1884 return HeapObject::RawField(this, kHeaderSize);
1885}
1886
1887
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001888bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001889 ASSERT(this->IsSmi() ||
1890 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001891 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001892 return this->IsSmi() || length() <= kFirstIndex;
1893}
1894
1895
1896int DescriptorArray::bit_field3_storage() {
1897 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1898 return Smi::cast(storage)->value();
1899}
1900
1901void DescriptorArray::set_bit_field3_storage(int value) {
1902 ASSERT(!IsEmpty());
1903 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001904}
1905
1906
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001907void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1908 Object* tmp = array->get(first);
1909 fast_set(array, first, array->get(second));
1910 fast_set(array, second, tmp);
1911}
1912
1913
1914int DescriptorArray::Search(String* name) {
1915 SLOW_ASSERT(IsSortedNoDuplicates());
1916
1917 // Check for empty descriptor array.
1918 int nof = number_of_descriptors();
1919 if (nof == 0) return kNotFound;
1920
1921 // Fast case: do linear search for small arrays.
1922 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001923 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001924 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001925 }
1926
1927 // Slow case: perform binary search.
1928 return BinarySearch(name, 0, nof - 1);
1929}
1930
1931
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001932int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001933 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001934 if (number == DescriptorLookupCache::kAbsent) {
1935 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001936 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001937 }
1938 return number;
1939}
1940
1941
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001942String* DescriptorArray::GetKey(int descriptor_number) {
1943 ASSERT(descriptor_number < number_of_descriptors());
1944 return String::cast(get(ToKeyIndex(descriptor_number)));
1945}
1946
1947
1948Object* DescriptorArray::GetValue(int descriptor_number) {
1949 ASSERT(descriptor_number < number_of_descriptors());
1950 return GetContentArray()->get(ToValueIndex(descriptor_number));
1951}
1952
1953
1954Smi* DescriptorArray::GetDetails(int descriptor_number) {
1955 ASSERT(descriptor_number < number_of_descriptors());
1956 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1957}
1958
1959
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001960PropertyType DescriptorArray::GetType(int descriptor_number) {
1961 ASSERT(descriptor_number < number_of_descriptors());
1962 return PropertyDetails(GetDetails(descriptor_number)).type();
1963}
1964
1965
1966int DescriptorArray::GetFieldIndex(int descriptor_number) {
1967 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1968}
1969
1970
1971JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1972 return JSFunction::cast(GetValue(descriptor_number));
1973}
1974
1975
1976Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1977 ASSERT(GetType(descriptor_number) == CALLBACKS);
1978 return GetValue(descriptor_number);
1979}
1980
1981
1982AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1983 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001984 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
1985 return reinterpret_cast<AccessorDescriptor*>(p->address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001986}
1987
1988
1989bool DescriptorArray::IsProperty(int descriptor_number) {
1990 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1991}
1992
1993
1994bool DescriptorArray::IsTransition(int descriptor_number) {
1995 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001996 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
1997 t == EXTERNAL_ARRAY_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001998}
1999
2000
2001bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
2002 return GetType(descriptor_number) == NULL_DESCRIPTOR;
2003}
2004
2005
2006bool DescriptorArray::IsDontEnum(int descriptor_number) {
2007 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
2008}
2009
2010
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002011void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2012 desc->Init(GetKey(descriptor_number),
2013 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002014 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002015}
2016
2017
2018void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
2019 // Range check.
2020 ASSERT(descriptor_number < number_of_descriptors());
2021
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00002022 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002023 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
2024 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002025
2026 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
2027 FixedArray* content_array = GetContentArray();
2028 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
2029 fast_set(content_array, ToDetailsIndex(descriptor_number),
2030 desc->GetDetails().AsSmi());
2031}
2032
2033
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002034void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
2035 Descriptor desc;
2036 src->Get(src_index, &desc);
2037 Set(index, &desc);
2038}
2039
2040
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002041void DescriptorArray::Swap(int first, int second) {
2042 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
2043 FixedArray* content_array = GetContentArray();
2044 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
2045 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
2046}
2047
2048
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002049template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002050int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2051 const int kMinCapacity = 32;
2052 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2053 if (capacity < kMinCapacity) {
2054 capacity = kMinCapacity; // Guarantee min capacity.
2055 }
2056 return capacity;
2057}
2058
2059
2060template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002061int HashTable<Shape, Key>::FindEntry(Key key) {
2062 return FindEntry(GetIsolate(), key);
2063}
2064
2065
2066// Find entry for key otherwise return kNotFound.
2067template<typename Shape, typename Key>
2068int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2069 uint32_t capacity = Capacity();
2070 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
2071 uint32_t count = 1;
2072 // EnsureCapacity will guarantee the hash table is never full.
2073 while (true) {
2074 Object* element = KeyAt(entry);
2075 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
2076 if (element != isolate->heap()->null_value() &&
2077 Shape::IsMatch(key, element)) return entry;
2078 entry = NextProbe(entry, count++, capacity);
2079 }
2080 return kNotFound;
2081}
2082
2083
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002084bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002085 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002086 if (!max_index_object->IsSmi()) return false;
2087 return 0 !=
2088 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2089}
2090
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002091uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002092 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002093 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002094 if (!max_index_object->IsSmi()) return 0;
2095 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2096 return value >> kRequiresSlowElementsTagSize;
2097}
2098
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002099void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002100 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002101}
2102
2103
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002104// ------------------------------------
2105// Cast operations
2106
2107
2108CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002109CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002110CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002111CAST_ACCESSOR(DeoptimizationInputData)
2112CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002113CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002114CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002115CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002116CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002117CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002118CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002119CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002120CAST_ACCESSOR(String)
2121CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002122CAST_ACCESSOR(SeqAsciiString)
2123CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002124CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002125CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002126CAST_ACCESSOR(ExternalString)
2127CAST_ACCESSOR(ExternalAsciiString)
2128CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002129CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002130CAST_ACCESSOR(JSObject)
2131CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002132CAST_ACCESSOR(HeapObject)
2133CAST_ACCESSOR(HeapNumber)
2134CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002135CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002136CAST_ACCESSOR(SharedFunctionInfo)
2137CAST_ACCESSOR(Map)
2138CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002139CAST_ACCESSOR(GlobalObject)
2140CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002141CAST_ACCESSOR(JSGlobalObject)
2142CAST_ACCESSOR(JSBuiltinsObject)
2143CAST_ACCESSOR(Code)
2144CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002145CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002146CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002147CAST_ACCESSOR(JSFunctionProxy)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002148CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002149CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002150CAST_ACCESSOR(ByteArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00002151CAST_ACCESSOR(ExternalArray)
2152CAST_ACCESSOR(ExternalByteArray)
2153CAST_ACCESSOR(ExternalUnsignedByteArray)
2154CAST_ACCESSOR(ExternalShortArray)
2155CAST_ACCESSOR(ExternalUnsignedShortArray)
2156CAST_ACCESSOR(ExternalIntArray)
2157CAST_ACCESSOR(ExternalUnsignedIntArray)
2158CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002159CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002160CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002161CAST_ACCESSOR(Struct)
2162
2163
2164#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2165 STRUCT_LIST(MAKE_STRUCT_CAST)
2166#undef MAKE_STRUCT_CAST
2167
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002168
2169template <typename Shape, typename Key>
2170HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002171 ASSERT(obj->IsHashTable());
2172 return reinterpret_cast<HashTable*>(obj);
2173}
2174
2175
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002176SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002177
ager@chromium.orgac091b72010-05-05 07:34:42 +00002178SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002179
2180
2181uint32_t String::hash_field() {
2182 return READ_UINT32_FIELD(this, kHashFieldOffset);
2183}
2184
2185
2186void String::set_hash_field(uint32_t value) {
2187 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002188#if V8_HOST_ARCH_64_BIT
2189 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2190#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002191}
2192
2193
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002194bool String::Equals(String* other) {
2195 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002196 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2197 return false;
2198 }
2199 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002200}
2201
2202
lrn@chromium.org303ada72010-10-27 09:33:13 +00002203MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002204 if (!StringShape(this).IsCons()) return this;
2205 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002206 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002207 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002208}
2209
2210
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002211String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002212 MaybeObject* flat = TryFlatten(pretenure);
2213 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002214 if (!flat->ToObject(&successfully_flattened)) return this;
2215 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002216}
2217
2218
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002219uint16_t String::Get(int index) {
2220 ASSERT(index >= 0 && index < length());
2221 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002222 case kSeqStringTag | kAsciiStringTag:
2223 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2224 case kSeqStringTag | kTwoByteStringTag:
2225 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2226 case kConsStringTag | kAsciiStringTag:
2227 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002228 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002229 case kExternalStringTag | kAsciiStringTag:
2230 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2231 case kExternalStringTag | kTwoByteStringTag:
2232 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002233 case kSlicedStringTag | kAsciiStringTag:
2234 case kSlicedStringTag | kTwoByteStringTag:
2235 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002236 default:
2237 break;
2238 }
2239
2240 UNREACHABLE();
2241 return 0;
2242}
2243
2244
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002245void String::Set(int index, uint16_t value) {
2246 ASSERT(index >= 0 && index < length());
2247 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002248
ager@chromium.org5ec48922009-05-05 07:25:34 +00002249 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002250 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2251 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002252}
2253
2254
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002255bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002256 if (!StringShape(this).IsCons()) return true;
2257 return ConsString::cast(this)->second()->length() == 0;
2258}
2259
2260
2261String* String::GetUnderlying() {
2262 // Giving direct access to underlying string only makes sense if the
2263 // wrapping string is already flattened.
2264 ASSERT(this->IsFlat());
2265 ASSERT(StringShape(this).IsIndirect());
2266 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2267 const int kUnderlyingOffset = SlicedString::kParentOffset;
2268 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002269}
2270
2271
ager@chromium.org7c537e22008-10-16 08:43:32 +00002272uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002273 ASSERT(index >= 0 && index < length());
2274 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2275}
2276
2277
ager@chromium.org7c537e22008-10-16 08:43:32 +00002278void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002279 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2280 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2281 static_cast<byte>(value));
2282}
2283
2284
ager@chromium.org7c537e22008-10-16 08:43:32 +00002285Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002286 return FIELD_ADDR(this, kHeaderSize);
2287}
2288
2289
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002290char* SeqAsciiString::GetChars() {
2291 return reinterpret_cast<char*>(GetCharsAddress());
2292}
2293
2294
ager@chromium.org7c537e22008-10-16 08:43:32 +00002295Address SeqTwoByteString::GetCharsAddress() {
2296 return FIELD_ADDR(this, kHeaderSize);
2297}
2298
2299
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002300uc16* SeqTwoByteString::GetChars() {
2301 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2302}
2303
2304
ager@chromium.org7c537e22008-10-16 08:43:32 +00002305uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002306 ASSERT(index >= 0 && index < length());
2307 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2308}
2309
2310
ager@chromium.org7c537e22008-10-16 08:43:32 +00002311void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002312 ASSERT(index >= 0 && index < length());
2313 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2314}
2315
2316
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002317int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002318 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002319}
2320
2321
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002322int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002323 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002324}
2325
2326
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002327String* SlicedString::parent() {
2328 return String::cast(READ_FIELD(this, kParentOffset));
2329}
2330
2331
2332void SlicedString::set_parent(String* parent) {
2333 ASSERT(parent->IsSeqString());
2334 WRITE_FIELD(this, kParentOffset, parent);
2335}
2336
2337
2338SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2339
2340
ager@chromium.org870a0b62008-11-04 11:43:05 +00002341String* ConsString::first() {
2342 return String::cast(READ_FIELD(this, kFirstOffset));
2343}
2344
2345
2346Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002347 return READ_FIELD(this, kFirstOffset);
2348}
2349
2350
ager@chromium.org870a0b62008-11-04 11:43:05 +00002351void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002352 WRITE_FIELD(this, kFirstOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002353 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002354}
2355
2356
ager@chromium.org870a0b62008-11-04 11:43:05 +00002357String* ConsString::second() {
2358 return String::cast(READ_FIELD(this, kSecondOffset));
2359}
2360
2361
2362Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002363 return READ_FIELD(this, kSecondOffset);
2364}
2365
2366
ager@chromium.org870a0b62008-11-04 11:43:05 +00002367void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002368 WRITE_FIELD(this, kSecondOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002369 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002370}
2371
2372
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002373ExternalAsciiString::Resource* ExternalAsciiString::resource() {
2374 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2375}
2376
2377
2378void ExternalAsciiString::set_resource(
2379 ExternalAsciiString::Resource* resource) {
2380 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2381}
2382
2383
2384ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
2385 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2386}
2387
2388
2389void ExternalTwoByteString::set_resource(
2390 ExternalTwoByteString::Resource* resource) {
2391 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2392}
2393
2394
ager@chromium.orgac091b72010-05-05 07:34:42 +00002395void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002396 set_finger_index(kEntriesIndex);
2397 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002398}
2399
2400
2401void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002402 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002403 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002404 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002405 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002406 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002407 MakeZeroSize();
2408}
2409
2410
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002411int JSFunctionResultCache::size() {
2412 return Smi::cast(get(kCacheSizeIndex))->value();
2413}
2414
2415
2416void JSFunctionResultCache::set_size(int size) {
2417 set(kCacheSizeIndex, Smi::FromInt(size));
2418}
2419
2420
2421int JSFunctionResultCache::finger_index() {
2422 return Smi::cast(get(kFingerIndex))->value();
2423}
2424
2425
2426void JSFunctionResultCache::set_finger_index(int finger_index) {
2427 set(kFingerIndex, Smi::FromInt(finger_index));
2428}
2429
2430
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002431byte ByteArray::get(int index) {
2432 ASSERT(index >= 0 && index < this->length());
2433 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2434}
2435
2436
2437void ByteArray::set(int index, byte value) {
2438 ASSERT(index >= 0 && index < this->length());
2439 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2440}
2441
2442
2443int ByteArray::get_int(int index) {
2444 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2445 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2446}
2447
2448
2449ByteArray* ByteArray::FromDataStartAddress(Address address) {
2450 ASSERT_TAG_ALIGNED(address);
2451 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2452}
2453
2454
2455Address ByteArray::GetDataStartAddress() {
2456 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2457}
2458
2459
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002460uint8_t* ExternalPixelArray::external_pixel_pointer() {
2461 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002462}
2463
2464
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002465uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002466 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002467 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002468 return ptr[index];
2469}
2470
2471
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002472MaybeObject* ExternalPixelArray::get(int index) {
2473 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2474}
2475
2476
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002477void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002478 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002479 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002480 ptr[index] = value;
2481}
2482
2483
ager@chromium.org3811b432009-10-28 14:53:37 +00002484void* ExternalArray::external_pointer() {
2485 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2486 return reinterpret_cast<void*>(ptr);
2487}
2488
2489
2490void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2491 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2492 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2493}
2494
2495
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002496int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002497 ASSERT((index >= 0) && (index < this->length()));
2498 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2499 return ptr[index];
2500}
2501
2502
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002503MaybeObject* ExternalByteArray::get(int index) {
2504 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2505}
2506
2507
ager@chromium.org3811b432009-10-28 14:53:37 +00002508void ExternalByteArray::set(int index, int8_t value) {
2509 ASSERT((index >= 0) && (index < this->length()));
2510 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2511 ptr[index] = value;
2512}
2513
2514
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002515uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002516 ASSERT((index >= 0) && (index < this->length()));
2517 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2518 return ptr[index];
2519}
2520
2521
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002522MaybeObject* ExternalUnsignedByteArray::get(int index) {
2523 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2524}
2525
2526
ager@chromium.org3811b432009-10-28 14:53:37 +00002527void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2528 ASSERT((index >= 0) && (index < this->length()));
2529 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2530 ptr[index] = value;
2531}
2532
2533
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002534int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002535 ASSERT((index >= 0) && (index < this->length()));
2536 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2537 return ptr[index];
2538}
2539
2540
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002541MaybeObject* ExternalShortArray::get(int index) {
2542 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2543}
2544
2545
ager@chromium.org3811b432009-10-28 14:53:37 +00002546void ExternalShortArray::set(int index, int16_t value) {
2547 ASSERT((index >= 0) && (index < this->length()));
2548 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2549 ptr[index] = value;
2550}
2551
2552
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002553uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002554 ASSERT((index >= 0) && (index < this->length()));
2555 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2556 return ptr[index];
2557}
2558
2559
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002560MaybeObject* ExternalUnsignedShortArray::get(int index) {
2561 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2562}
2563
2564
ager@chromium.org3811b432009-10-28 14:53:37 +00002565void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2566 ASSERT((index >= 0) && (index < this->length()));
2567 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2568 ptr[index] = value;
2569}
2570
2571
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002572int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002573 ASSERT((index >= 0) && (index < this->length()));
2574 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2575 return ptr[index];
2576}
2577
2578
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002579MaybeObject* ExternalIntArray::get(int index) {
2580 return GetHeap()->NumberFromInt32(get_scalar(index));
2581}
2582
2583
ager@chromium.org3811b432009-10-28 14:53:37 +00002584void ExternalIntArray::set(int index, int32_t value) {
2585 ASSERT((index >= 0) && (index < this->length()));
2586 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2587 ptr[index] = value;
2588}
2589
2590
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002591uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002592 ASSERT((index >= 0) && (index < this->length()));
2593 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2594 return ptr[index];
2595}
2596
2597
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002598MaybeObject* ExternalUnsignedIntArray::get(int index) {
2599 return GetHeap()->NumberFromUint32(get_scalar(index));
2600}
2601
2602
ager@chromium.org3811b432009-10-28 14:53:37 +00002603void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2604 ASSERT((index >= 0) && (index < this->length()));
2605 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2606 ptr[index] = value;
2607}
2608
2609
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002610float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002611 ASSERT((index >= 0) && (index < this->length()));
2612 float* ptr = static_cast<float*>(external_pointer());
2613 return ptr[index];
2614}
2615
2616
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002617MaybeObject* ExternalFloatArray::get(int index) {
2618 return GetHeap()->NumberFromDouble(get_scalar(index));
2619}
2620
2621
ager@chromium.org3811b432009-10-28 14:53:37 +00002622void ExternalFloatArray::set(int index, float value) {
2623 ASSERT((index >= 0) && (index < this->length()));
2624 float* ptr = static_cast<float*>(external_pointer());
2625 ptr[index] = value;
2626}
2627
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002628
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002629double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002630 ASSERT((index >= 0) && (index < this->length()));
2631 double* ptr = static_cast<double*>(external_pointer());
2632 return ptr[index];
2633}
2634
2635
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002636MaybeObject* ExternalDoubleArray::get(int index) {
2637 return GetHeap()->NumberFromDouble(get_scalar(index));
2638}
2639
2640
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002641void ExternalDoubleArray::set(int index, double value) {
2642 ASSERT((index >= 0) && (index < this->length()));
2643 double* ptr = static_cast<double*>(external_pointer());
2644 ptr[index] = value;
2645}
2646
2647
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002648int Map::visitor_id() {
2649 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2650}
2651
2652
2653void Map::set_visitor_id(int id) {
2654 ASSERT(0 <= id && id < 256);
2655 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2656}
2657
ager@chromium.org3811b432009-10-28 14:53:37 +00002658
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002659int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002660 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2661}
2662
2663
2664int Map::inobject_properties() {
2665 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002666}
2667
2668
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002669int Map::pre_allocated_property_fields() {
2670 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2671}
2672
2673
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002674int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002675 int instance_size = map->instance_size();
2676 if (instance_size != kVariableSizeSentinel) return instance_size;
2677 // We can ignore the "symbol" bit becase it is only set for symbols
2678 // and implies a string type.
2679 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002680 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002681 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002682 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002683 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002684 if (instance_type == ASCII_STRING_TYPE) {
2685 return SeqAsciiString::SizeFor(
2686 reinterpret_cast<SeqAsciiString*>(this)->length());
2687 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002688 if (instance_type == BYTE_ARRAY_TYPE) {
2689 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2690 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002691 if (instance_type == STRING_TYPE) {
2692 return SeqTwoByteString::SizeFor(
2693 reinterpret_cast<SeqTwoByteString*>(this)->length());
2694 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002695 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2696 return FixedDoubleArray::SizeFor(
2697 reinterpret_cast<FixedDoubleArray*>(this)->length());
2698 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002699 ASSERT(instance_type == CODE_TYPE);
2700 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002701}
2702
2703
2704void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002705 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002706 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002707 ASSERT(0 <= value && value < 256);
2708 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2709}
2710
2711
ager@chromium.org7c537e22008-10-16 08:43:32 +00002712void Map::set_inobject_properties(int value) {
2713 ASSERT(0 <= value && value < 256);
2714 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2715}
2716
2717
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002718void Map::set_pre_allocated_property_fields(int value) {
2719 ASSERT(0 <= value && value < 256);
2720 WRITE_BYTE_FIELD(this,
2721 kPreAllocatedPropertyFieldsOffset,
2722 static_cast<byte>(value));
2723}
2724
2725
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002726InstanceType Map::instance_type() {
2727 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2728}
2729
2730
2731void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002732 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2733}
2734
2735
2736int Map::unused_property_fields() {
2737 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2738}
2739
2740
2741void Map::set_unused_property_fields(int value) {
2742 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2743}
2744
2745
2746byte Map::bit_field() {
2747 return READ_BYTE_FIELD(this, kBitFieldOffset);
2748}
2749
2750
2751void Map::set_bit_field(byte value) {
2752 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2753}
2754
2755
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002756byte Map::bit_field2() {
2757 return READ_BYTE_FIELD(this, kBitField2Offset);
2758}
2759
2760
2761void Map::set_bit_field2(byte value) {
2762 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2763}
2764
2765
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002766void Map::set_non_instance_prototype(bool value) {
2767 if (value) {
2768 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2769 } else {
2770 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2771 }
2772}
2773
2774
2775bool Map::has_non_instance_prototype() {
2776 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2777}
2778
2779
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002780void Map::set_function_with_prototype(bool value) {
2781 if (value) {
2782 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2783 } else {
2784 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2785 }
2786}
2787
2788
2789bool Map::function_with_prototype() {
2790 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2791}
2792
2793
ager@chromium.org870a0b62008-11-04 11:43:05 +00002794void Map::set_is_access_check_needed(bool access_check_needed) {
2795 if (access_check_needed) {
2796 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2797 } else {
2798 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2799 }
2800}
2801
2802
2803bool Map::is_access_check_needed() {
2804 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2805}
2806
2807
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002808void Map::set_is_extensible(bool value) {
2809 if (value) {
2810 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2811 } else {
2812 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2813 }
2814}
2815
2816bool Map::is_extensible() {
2817 return ((1 << kIsExtensible) & bit_field2()) != 0;
2818}
2819
2820
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002821void Map::set_attached_to_shared_function_info(bool value) {
2822 if (value) {
2823 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2824 } else {
2825 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2826 }
2827}
2828
2829bool Map::attached_to_shared_function_info() {
2830 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2831}
2832
2833
2834void Map::set_is_shared(bool value) {
2835 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002836 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002837 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002838 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002839 }
2840}
2841
2842bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002843 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002844}
2845
2846
2847JSFunction* Map::unchecked_constructor() {
2848 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2849}
2850
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002851
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002852FixedArray* Map::unchecked_prototype_transitions() {
2853 return reinterpret_cast<FixedArray*>(
2854 READ_FIELD(this, kPrototypeTransitionsOffset));
2855}
2856
2857
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002858Code::Flags Code::flags() {
2859 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2860}
2861
2862
2863void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002864 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002865 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002866 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2867 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002868 ExtractArgumentsCountFromFlags(flags) >= 0);
2869 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2870}
2871
2872
2873Code::Kind Code::kind() {
2874 return ExtractKindFromFlags(flags());
2875}
2876
2877
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002878InLoopFlag Code::ic_in_loop() {
2879 return ExtractICInLoopFromFlags(flags());
2880}
2881
2882
kasper.lund7276f142008-07-30 08:49:36 +00002883InlineCacheState Code::ic_state() {
2884 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002885 // Only allow uninitialized or debugger states for non-IC code
2886 // objects. This is used in the debugger to determine whether or not
2887 // a call to code object has been replaced with a debug break call.
2888 ASSERT(is_inline_cache_stub() ||
2889 result == UNINITIALIZED ||
2890 result == DEBUG_BREAK ||
2891 result == DEBUG_PREPARE_STEP_IN);
2892 return result;
2893}
2894
2895
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002896Code::ExtraICState Code::extra_ic_state() {
2897 ASSERT(is_inline_cache_stub());
2898 return ExtractExtraICStateFromFlags(flags());
2899}
2900
2901
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002902PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002903 return ExtractTypeFromFlags(flags());
2904}
2905
2906
2907int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002908 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002909 return ExtractArgumentsCountFromFlags(flags());
2910}
2911
2912
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002913int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002914 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002915 kind() == UNARY_OP_IC ||
2916 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002917 kind() == COMPARE_IC ||
2918 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002919 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002920}
2921
2922
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002923void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002924 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002925 kind() == UNARY_OP_IC ||
2926 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002927 kind() == COMPARE_IC ||
2928 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002929 ASSERT(0 <= major && major < 256);
2930 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002931}
2932
2933
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002934bool Code::optimizable() {
2935 ASSERT(kind() == FUNCTION);
2936 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2937}
2938
2939
2940void Code::set_optimizable(bool value) {
2941 ASSERT(kind() == FUNCTION);
2942 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2943}
2944
2945
2946bool Code::has_deoptimization_support() {
2947 ASSERT(kind() == FUNCTION);
2948 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2949}
2950
2951
2952void Code::set_has_deoptimization_support(bool value) {
2953 ASSERT(kind() == FUNCTION);
2954 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2955}
2956
2957
2958int Code::allow_osr_at_loop_nesting_level() {
2959 ASSERT(kind() == FUNCTION);
2960 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2961}
2962
2963
2964void Code::set_allow_osr_at_loop_nesting_level(int level) {
2965 ASSERT(kind() == FUNCTION);
2966 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2967 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2968}
2969
2970
2971unsigned Code::stack_slots() {
2972 ASSERT(kind() == OPTIMIZED_FUNCTION);
2973 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2974}
2975
2976
2977void Code::set_stack_slots(unsigned slots) {
2978 ASSERT(kind() == OPTIMIZED_FUNCTION);
2979 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2980}
2981
2982
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002983unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002984 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002985 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002986}
2987
2988
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002989void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002990 ASSERT(kind() == OPTIMIZED_FUNCTION);
2991 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002992 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002993}
2994
2995
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002996unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002997 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002998 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002999}
3000
3001
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003002void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003003 ASSERT(kind() == FUNCTION);
3004 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003005 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003006}
3007
3008
3009CheckType Code::check_type() {
3010 ASSERT(is_call_stub() || is_keyed_call_stub());
3011 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3012 return static_cast<CheckType>(type);
3013}
3014
3015
3016void Code::set_check_type(CheckType value) {
3017 ASSERT(is_call_stub() || is_keyed_call_stub());
3018 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3019}
3020
3021
danno@chromium.org40cb8782011-05-25 07:58:50 +00003022byte Code::unary_op_type() {
3023 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003024 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3025}
3026
3027
danno@chromium.org40cb8782011-05-25 07:58:50 +00003028void Code::set_unary_op_type(byte value) {
3029 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003030 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3031}
3032
3033
danno@chromium.org40cb8782011-05-25 07:58:50 +00003034byte Code::binary_op_type() {
3035 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003036 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3037}
3038
3039
danno@chromium.org40cb8782011-05-25 07:58:50 +00003040void Code::set_binary_op_type(byte value) {
3041 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003042 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3043}
3044
3045
danno@chromium.org40cb8782011-05-25 07:58:50 +00003046byte Code::binary_op_result_type() {
3047 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003048 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3049}
3050
3051
danno@chromium.org40cb8782011-05-25 07:58:50 +00003052void Code::set_binary_op_result_type(byte value) {
3053 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003054 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3055}
3056
3057
3058byte Code::compare_state() {
3059 ASSERT(is_compare_ic_stub());
3060 return READ_BYTE_FIELD(this, kCompareStateOffset);
3061}
3062
3063
3064void Code::set_compare_state(byte value) {
3065 ASSERT(is_compare_ic_stub());
3066 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3067}
3068
3069
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003070byte Code::to_boolean_state() {
3071 ASSERT(is_to_boolean_ic_stub());
3072 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3073}
3074
3075
3076void Code::set_to_boolean_state(byte value) {
3077 ASSERT(is_to_boolean_ic_stub());
3078 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3079}
3080
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003081bool Code::is_inline_cache_stub() {
3082 Kind kind = this->kind();
3083 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3084}
3085
3086
3087Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003088 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00003089 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003090 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003091 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003092 int argc,
3093 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003094 // Extra IC state is only allowed for call IC stubs or for store IC
3095 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003096 ASSERT(extra_ic_state == kNoExtraICState ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003097 (kind == CALL_IC) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00003098 (kind == STORE_IC) ||
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003099 (kind == KEYED_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003100 // Compute the bit mask.
3101 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003102 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00003103 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003104 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003105 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003106 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003107 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003108 // Cast to flags and validate result before returning it.
3109 Flags result = static_cast<Flags>(bits);
3110 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00003111 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003112 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003113 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003114 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003115 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
3116 return result;
3117}
3118
3119
3120Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3121 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003122 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003123 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003124 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003125 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003126 return ComputeFlags(
3127 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003128}
3129
3130
3131Code::Kind Code::ExtractKindFromFlags(Flags flags) {
3132 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
3133 return static_cast<Kind>(bits);
3134}
3135
3136
kasper.lund7276f142008-07-30 08:49:36 +00003137InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
3138 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003139 return static_cast<InlineCacheState>(bits);
3140}
3141
3142
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003143Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
3144 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
3145 return static_cast<ExtraICState>(bits);
3146}
3147
3148
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003149InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
3150 int bits = (flags & kFlagsICInLoopMask);
3151 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
3152}
3153
3154
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003155PropertyType Code::ExtractTypeFromFlags(Flags flags) {
3156 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
3157 return static_cast<PropertyType>(bits);
3158}
3159
3160
3161int Code::ExtractArgumentsCountFromFlags(Flags flags) {
3162 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
3163}
3164
3165
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003166InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
3167 int bits = (flags & kFlagsCacheInPrototypeMapMask);
3168 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
3169}
3170
3171
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003172Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
3173 int bits = flags & ~kFlagsTypeMask;
3174 return static_cast<Flags>(bits);
3175}
3176
3177
ager@chromium.org8bb60582008-12-11 12:02:20 +00003178Code* Code::GetCodeFromTargetAddress(Address address) {
3179 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3180 // GetCodeFromTargetAddress might be called when marking objects during mark
3181 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3182 // Code::cast. Code::cast does not work when the object's map is
3183 // marked.
3184 Code* result = reinterpret_cast<Code*>(code);
3185 return result;
3186}
3187
3188
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003189Isolate* Map::isolate() {
3190 return heap()->isolate();
3191}
3192
3193
3194Heap* Map::heap() {
3195 // NOTE: address() helper is not used to save one instruction.
3196 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3197 ASSERT(heap != NULL);
3198 ASSERT(heap->isolate() == Isolate::Current());
3199 return heap;
3200}
3201
3202
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003203Heap* Code::heap() {
3204 // NOTE: address() helper is not used to save one instruction.
3205 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3206 ASSERT(heap != NULL);
3207 ASSERT(heap->isolate() == Isolate::Current());
3208 return heap;
3209}
3210
3211
3212Isolate* Code::isolate() {
3213 return heap()->isolate();
3214}
3215
3216
3217Heap* JSGlobalPropertyCell::heap() {
3218 // NOTE: address() helper is not used to save one instruction.
3219 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3220 ASSERT(heap != NULL);
3221 ASSERT(heap->isolate() == Isolate::Current());
3222 return heap;
3223}
3224
3225
3226Isolate* JSGlobalPropertyCell::isolate() {
3227 return heap()->isolate();
3228}
3229
3230
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003231Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3232 return HeapObject::
3233 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3234}
3235
3236
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003237Object* Map::prototype() {
3238 return READ_FIELD(this, kPrototypeOffset);
3239}
3240
3241
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003242void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003243 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003244 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003245 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003246}
3247
3248
lrn@chromium.org303ada72010-10-27 09:33:13 +00003249MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003250 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003251 Object* obj;
3252 { MaybeObject* maybe_obj = CopyDropTransitions();
3253 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3254 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003255 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003256 new_map->set_elements_kind(JSObject::FAST_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003257 isolate()->counters()->map_to_fast_elements()->Increment();
3258 return new_map;
3259}
3260
3261
3262MaybeObject* Map::GetFastDoubleElementsMap() {
3263 if (has_fast_double_elements()) return this;
3264 Object* obj;
3265 { MaybeObject* maybe_obj = CopyDropTransitions();
3266 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3267 }
3268 Map* new_map = Map::cast(obj);
3269 new_map->set_elements_kind(JSObject::FAST_DOUBLE_ELEMENTS);
3270 isolate()->counters()->map_to_fast_double_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003271 return new_map;
3272}
3273
3274
lrn@chromium.org303ada72010-10-27 09:33:13 +00003275MaybeObject* Map::GetSlowElementsMap() {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003276 if (!has_fast_elements() && !has_fast_double_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003277 Object* obj;
3278 { MaybeObject* maybe_obj = CopyDropTransitions();
3279 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3280 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003281 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003282 new_map->set_elements_kind(JSObject::DICTIONARY_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003283 isolate()->counters()->map_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003284 return new_map;
3285}
3286
3287
danno@chromium.org40cb8782011-05-25 07:58:50 +00003288DescriptorArray* Map::instance_descriptors() {
3289 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3290 if (object->IsSmi()) {
3291 return HEAP->empty_descriptor_array();
3292 } else {
3293 return DescriptorArray::cast(object);
3294 }
3295}
3296
3297
3298void Map::init_instance_descriptors() {
3299 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3300}
3301
3302
3303void Map::clear_instance_descriptors() {
3304 Object* object = READ_FIELD(this,
3305 kInstanceDescriptorsOrBitField3Offset);
3306 if (!object->IsSmi()) {
3307 WRITE_FIELD(
3308 this,
3309 kInstanceDescriptorsOrBitField3Offset,
3310 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3311 }
3312}
3313
3314
3315void Map::set_instance_descriptors(DescriptorArray* value,
3316 WriteBarrierMode mode) {
3317 Object* object = READ_FIELD(this,
3318 kInstanceDescriptorsOrBitField3Offset);
3319 if (value == isolate()->heap()->empty_descriptor_array()) {
3320 clear_instance_descriptors();
3321 return;
3322 } else {
3323 if (object->IsSmi()) {
3324 value->set_bit_field3_storage(Smi::cast(object)->value());
3325 } else {
3326 value->set_bit_field3_storage(
3327 DescriptorArray::cast(object)->bit_field3_storage());
3328 }
3329 }
3330 ASSERT(!is_shared());
3331 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
3332 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3333 this,
3334 kInstanceDescriptorsOrBitField3Offset,
3335 mode);
3336}
3337
3338
3339int Map::bit_field3() {
3340 Object* object = READ_FIELD(this,
3341 kInstanceDescriptorsOrBitField3Offset);
3342 if (object->IsSmi()) {
3343 return Smi::cast(object)->value();
3344 } else {
3345 return DescriptorArray::cast(object)->bit_field3_storage();
3346 }
3347}
3348
3349
3350void Map::set_bit_field3(int value) {
3351 ASSERT(Smi::IsValid(value));
3352 Object* object = READ_FIELD(this,
3353 kInstanceDescriptorsOrBitField3Offset);
3354 if (object->IsSmi()) {
3355 WRITE_FIELD(this,
3356 kInstanceDescriptorsOrBitField3Offset,
3357 Smi::FromInt(value));
3358 } else {
3359 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3360 }
3361}
3362
3363
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003364ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003365ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003366ACCESSORS(Map, constructor, Object, kConstructorOffset)
3367
3368ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
3369ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003370ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
3371 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003372
3373ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3374ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003375ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003376
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003377ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003378
3379ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3380ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3381ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3382ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3383ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3384
3385ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3386ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3387ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3388
3389ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3390ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3391ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3392ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3393ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3394ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3395
3396ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3397ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3398
3399ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3400ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3401
3402ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3403ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003404ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3405 kPropertyAccessorsOffset)
3406ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3407 kPrototypeTemplateOffset)
3408ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3409ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3410 kNamedPropertyHandlerOffset)
3411ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3412 kIndexedPropertyHandlerOffset)
3413ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3414 kInstanceTemplateOffset)
3415ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3416ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003417ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3418 kInstanceCallHandlerOffset)
3419ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3420 kAccessCheckInfoOffset)
3421ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3422
3423ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003424ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3425 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003426
3427ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3428ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3429
3430ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3431
3432ACCESSORS(Script, source, Object, kSourceOffset)
3433ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003434ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003435ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3436ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003437ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003438ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003439ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003440ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003441ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003442ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003443ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003444ACCESSORS(Script, eval_from_instructions_offset, Smi,
3445 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003446
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003447#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003448ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3449ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3450ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3451ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3452
3453ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3454ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3455ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3456ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003457#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003458
3459ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003460ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3461ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003462ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3463 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003464ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003465ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3466ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003467ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003468ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3469 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003470
3471BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3472 kHiddenPrototypeBit)
3473BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3474BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3475 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003476BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3477 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003478BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3479 kIsExpressionBit)
3480BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3481 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003482BOOL_GETTER(SharedFunctionInfo,
3483 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003484 has_only_simple_this_property_assignments,
3485 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003486BOOL_ACCESSORS(SharedFunctionInfo,
3487 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003488 allows_lazy_compilation,
3489 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003490BOOL_ACCESSORS(SharedFunctionInfo,
3491 compiler_hints,
3492 uses_arguments,
3493 kUsesArguments)
3494BOOL_ACCESSORS(SharedFunctionInfo,
3495 compiler_hints,
3496 has_duplicate_parameters,
3497 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003498
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003499
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003500#if V8_HOST_ARCH_32_BIT
3501SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3502SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003503 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003504SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003505 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003506SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3507SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003508 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003509SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3510SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003511 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003512SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003513 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003514SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003515 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003516SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003517#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003518
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003519#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003520 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003521 int holder::name() { \
3522 int value = READ_INT_FIELD(this, offset); \
3523 ASSERT(kHeapObjectTag == 1); \
3524 ASSERT((value & kHeapObjectTag) == 0); \
3525 return value >> 1; \
3526 } \
3527 void holder::set_##name(int value) { \
3528 ASSERT(kHeapObjectTag == 1); \
3529 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3530 (value & 0xC0000000) == 0x000000000); \
3531 WRITE_INT_FIELD(this, \
3532 offset, \
3533 (value << 1) & ~kHeapObjectTag); \
3534 }
3535
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003536#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3537 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003538 INT_ACCESSORS(holder, name, offset)
3539
3540
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003541PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003542PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3543 formal_parameter_count,
3544 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003545
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003546PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3547 expected_nof_properties,
3548 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003549PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3550
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003551PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3552PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3553 start_position_and_type,
3554 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003555
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003556PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3557 function_token_position,
3558 kFunctionTokenPositionOffset)
3559PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3560 compiler_hints,
3561 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003562
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003563PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3564 this_property_assignments_count,
3565 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003566PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003567#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003568
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003569
3570int SharedFunctionInfo::construction_count() {
3571 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3572}
3573
3574
3575void SharedFunctionInfo::set_construction_count(int value) {
3576 ASSERT(0 <= value && value < 256);
3577 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3578}
3579
3580
whesse@chromium.org7b260152011-06-20 15:33:18 +00003581BOOL_ACCESSORS(SharedFunctionInfo,
3582 compiler_hints,
3583 live_objects_may_exist,
3584 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003585
3586
3587bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003588 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003589}
3590
3591
whesse@chromium.org7b260152011-06-20 15:33:18 +00003592BOOL_GETTER(SharedFunctionInfo,
3593 compiler_hints,
3594 optimization_disabled,
3595 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003596
3597
3598void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3599 set_compiler_hints(BooleanBit::set(compiler_hints(),
3600 kOptimizationDisabled,
3601 disable));
3602 // If disabling optimizations we reflect that in the code object so
3603 // it will not be counted as optimizable code.
3604 if ((code()->kind() == Code::FUNCTION) && disable) {
3605 code()->set_optimizable(false);
3606 }
3607}
3608
3609
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003610BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, strict_mode,
whesse@chromium.org7b260152011-06-20 15:33:18 +00003611 kStrictModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003612BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3613BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3614 name_should_print_as_anonymous,
3615 kNameShouldPrintAsAnonymous)
3616BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3617BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003618
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003619ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3620ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3621
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003622ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3623
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003624bool Script::HasValidSource() {
3625 Object* src = this->source();
3626 if (!src->IsString()) return true;
3627 String* src_str = String::cast(src);
3628 if (!StringShape(src_str).IsExternal()) return true;
3629 if (src_str->IsAsciiRepresentation()) {
3630 return ExternalAsciiString::cast(src)->resource() != NULL;
3631 } else if (src_str->IsTwoByteRepresentation()) {
3632 return ExternalTwoByteString::cast(src)->resource() != NULL;
3633 }
3634 return true;
3635}
3636
3637
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003638void SharedFunctionInfo::DontAdaptArguments() {
3639 ASSERT(code()->kind() == Code::BUILTIN);
3640 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3641}
3642
3643
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003644int SharedFunctionInfo::start_position() {
3645 return start_position_and_type() >> kStartPositionShift;
3646}
3647
3648
3649void SharedFunctionInfo::set_start_position(int start_position) {
3650 set_start_position_and_type((start_position << kStartPositionShift)
3651 | (start_position_and_type() & ~kStartPositionMask));
3652}
3653
3654
3655Code* SharedFunctionInfo::code() {
3656 return Code::cast(READ_FIELD(this, kCodeOffset));
3657}
3658
3659
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003660Code* SharedFunctionInfo::unchecked_code() {
3661 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3662}
3663
3664
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003665void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003666 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003667 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003668}
3669
3670
ager@chromium.orgb5737492010-07-15 09:29:43 +00003671SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3672 return reinterpret_cast<SerializedScopeInfo*>(
3673 READ_FIELD(this, kScopeInfoOffset));
3674}
3675
3676
3677void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3678 WriteBarrierMode mode) {
3679 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003680 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003681}
3682
3683
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003684Smi* SharedFunctionInfo::deopt_counter() {
3685 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3686}
3687
3688
3689void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3690 WRITE_FIELD(this, kDeoptCounterOffset, value);
3691}
3692
3693
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003694bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003695 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003696 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003697}
3698
3699
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003700bool SharedFunctionInfo::IsApiFunction() {
3701 return function_data()->IsFunctionTemplateInfo();
3702}
3703
3704
3705FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3706 ASSERT(IsApiFunction());
3707 return FunctionTemplateInfo::cast(function_data());
3708}
3709
3710
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003711bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003712 return function_data()->IsSmi();
3713}
3714
3715
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003716BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3717 ASSERT(HasBuiltinFunctionId());
3718 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003719}
3720
3721
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003722int SharedFunctionInfo::code_age() {
3723 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3724}
3725
3726
3727void SharedFunctionInfo::set_code_age(int code_age) {
3728 set_compiler_hints(compiler_hints() |
3729 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3730}
3731
3732
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003733bool SharedFunctionInfo::has_deoptimization_support() {
3734 Code* code = this->code();
3735 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3736}
3737
3738
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003739bool JSFunction::IsBuiltin() {
3740 return context()->global()->IsJSBuiltinsObject();
3741}
3742
3743
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003744bool JSFunction::NeedsArgumentsAdaption() {
3745 return shared()->formal_parameter_count() !=
3746 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3747}
3748
3749
3750bool JSFunction::IsOptimized() {
3751 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3752}
3753
3754
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003755bool JSFunction::IsOptimizable() {
3756 return code()->kind() == Code::FUNCTION && code()->optimizable();
3757}
3758
3759
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003760bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003761 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003762}
3763
3764
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003765Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003766 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003767}
3768
3769
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003770Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003771 return reinterpret_cast<Code*>(
3772 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003773}
3774
3775
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003776void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003777 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003778 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003779 Address entry = value->entry();
3780 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003781}
3782
3783
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003784void JSFunction::ReplaceCode(Code* code) {
3785 bool was_optimized = IsOptimized();
3786 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3787
3788 set_code(code);
3789
3790 // Add/remove the function from the list of optimized functions for this
3791 // context based on the state change.
3792 if (!was_optimized && is_optimized) {
3793 context()->global_context()->AddOptimizedFunction(this);
3794 }
3795 if (was_optimized && !is_optimized) {
3796 context()->global_context()->RemoveOptimizedFunction(this);
3797 }
3798}
3799
3800
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003801Context* JSFunction::context() {
3802 return Context::cast(READ_FIELD(this, kContextOffset));
3803}
3804
3805
3806Object* JSFunction::unchecked_context() {
3807 return READ_FIELD(this, kContextOffset);
3808}
3809
3810
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003811SharedFunctionInfo* JSFunction::unchecked_shared() {
3812 return reinterpret_cast<SharedFunctionInfo*>(
3813 READ_FIELD(this, kSharedFunctionInfoOffset));
3814}
3815
3816
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003817void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003818 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003819 WRITE_FIELD(this, kContextOffset, value);
3820 WRITE_BARRIER(this, kContextOffset);
3821}
3822
3823ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3824 kPrototypeOrInitialMapOffset)
3825
3826
3827Map* JSFunction::initial_map() {
3828 return Map::cast(prototype_or_initial_map());
3829}
3830
3831
3832void JSFunction::set_initial_map(Map* value) {
3833 set_prototype_or_initial_map(value);
3834}
3835
3836
3837bool JSFunction::has_initial_map() {
3838 return prototype_or_initial_map()->IsMap();
3839}
3840
3841
3842bool JSFunction::has_instance_prototype() {
3843 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3844}
3845
3846
3847bool JSFunction::has_prototype() {
3848 return map()->has_non_instance_prototype() || has_instance_prototype();
3849}
3850
3851
3852Object* JSFunction::instance_prototype() {
3853 ASSERT(has_instance_prototype());
3854 if (has_initial_map()) return initial_map()->prototype();
3855 // When there is no initial map and the prototype is a JSObject, the
3856 // initial map field is used for the prototype field.
3857 return prototype_or_initial_map();
3858}
3859
3860
3861Object* JSFunction::prototype() {
3862 ASSERT(has_prototype());
3863 // If the function's prototype property has been set to a non-JSObject
3864 // value, that value is stored in the constructor field of the map.
3865 if (map()->has_non_instance_prototype()) return map()->constructor();
3866 return instance_prototype();
3867}
3868
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003869bool JSFunction::should_have_prototype() {
3870 return map()->function_with_prototype();
3871}
3872
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003873
3874bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003875 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003876}
3877
3878
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003879int JSFunction::NumberOfLiterals() {
3880 return literals()->length();
3881}
3882
3883
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003884Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003885 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003886 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003887}
3888
3889
3890void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3891 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003892 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003893 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3894 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3895}
3896
3897
3898Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003899 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003900 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3901}
3902
3903
3904void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3905 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003906 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003907 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003908 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003909}
3910
3911
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003912ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003913ACCESSORS(JSProxy, padding, Object, kPaddingOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003914
3915
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003916ACCESSORS(JSWeakMap, table, ObjectHashTable, kTableOffset)
3917ACCESSORS_GCSAFE(JSWeakMap, next, Object, kNextOffset)
3918
3919
3920ObjectHashTable* JSWeakMap::unchecked_table() {
3921 return reinterpret_cast<ObjectHashTable*>(READ_FIELD(this, kTableOffset));
3922}
3923
3924
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003925Address Foreign::address() {
3926 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003927}
3928
3929
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003930void Foreign::set_address(Address value) {
3931 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003932}
3933
3934
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003935ACCESSORS(JSValue, value, Object, kValueOffset)
3936
3937
3938JSValue* JSValue::cast(Object* obj) {
3939 ASSERT(obj->IsJSValue());
3940 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3941 return reinterpret_cast<JSValue*>(obj);
3942}
3943
3944
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003945ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3946ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3947ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3948ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3949ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3950SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3951SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3952
3953
3954JSMessageObject* JSMessageObject::cast(Object* obj) {
3955 ASSERT(obj->IsJSMessageObject());
3956 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3957 return reinterpret_cast<JSMessageObject*>(obj);
3958}
3959
3960
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003961INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003962ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003963ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003964ACCESSORS(Code, next_code_flushing_candidate,
3965 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003966
3967
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003968byte* Code::instruction_start() {
3969 return FIELD_ADDR(this, kHeaderSize);
3970}
3971
3972
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003973byte* Code::instruction_end() {
3974 return instruction_start() + instruction_size();
3975}
3976
3977
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003978int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003979 return RoundUp(instruction_size(), kObjectAlignment);
3980}
3981
3982
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003983FixedArray* Code::unchecked_deoptimization_data() {
3984 return reinterpret_cast<FixedArray*>(
3985 READ_FIELD(this, kDeoptimizationDataOffset));
3986}
3987
3988
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003989ByteArray* Code::unchecked_relocation_info() {
3990 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003991}
3992
3993
3994byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003995 return unchecked_relocation_info()->GetDataStartAddress();
3996}
3997
3998
3999int Code::relocation_size() {
4000 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004001}
4002
4003
4004byte* Code::entry() {
4005 return instruction_start();
4006}
4007
4008
4009bool Code::contains(byte* pc) {
4010 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00004011 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004012}
4013
4014
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004015ACCESSORS(JSArray, length, Object, kLengthOffset)
4016
4017
ager@chromium.org236ad962008-09-25 09:45:57 +00004018ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004019
4020
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004021JSRegExp::Type JSRegExp::TypeTag() {
4022 Object* data = this->data();
4023 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4024 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4025 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004026}
4027
4028
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004029JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4030 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4031 return static_cast<JSRegExp::Type>(smi->value());
4032}
4033
4034
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004035int JSRegExp::CaptureCount() {
4036 switch (TypeTag()) {
4037 case ATOM:
4038 return 0;
4039 case IRREGEXP:
4040 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4041 default:
4042 UNREACHABLE();
4043 return -1;
4044 }
4045}
4046
4047
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004048JSRegExp::Flags JSRegExp::GetFlags() {
4049 ASSERT(this->data()->IsFixedArray());
4050 Object* data = this->data();
4051 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4052 return Flags(smi->value());
4053}
4054
4055
4056String* JSRegExp::Pattern() {
4057 ASSERT(this->data()->IsFixedArray());
4058 Object* data = this->data();
4059 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4060 return pattern;
4061}
4062
4063
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004064Object* JSRegExp::DataAt(int index) {
4065 ASSERT(TypeTag() != NOT_COMPILED);
4066 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004067}
4068
4069
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004070Object* JSRegExp::DataAtUnchecked(int index) {
4071 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4072 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4073 return READ_FIELD(fa, offset);
4074}
4075
4076
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004077void JSRegExp::SetDataAt(int index, Object* value) {
4078 ASSERT(TypeTag() != NOT_COMPILED);
4079 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4080 FixedArray::cast(data())->set(index, value);
4081}
4082
4083
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004084void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4085 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4086 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4087 if (value->IsSmi()) {
4088 fa->set_unchecked(index, Smi::cast(value));
4089 } else {
4090 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4091 }
4092}
4093
4094
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004095JSObject::ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004096 ElementsKind kind = map()->elements_kind();
4097 ASSERT((kind == FAST_ELEMENTS &&
4098 (elements()->map() == GetHeap()->fixed_array_map() ||
4099 elements()->map() == GetHeap()->fixed_cow_array_map())) ||
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004100 (kind == FAST_DOUBLE_ELEMENTS &&
4101 elements()->IsFixedDoubleArray()) ||
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004102 (kind == DICTIONARY_ELEMENTS &&
4103 elements()->IsFixedArray() &&
4104 elements()->IsDictionary()) ||
4105 (kind > DICTIONARY_ELEMENTS));
4106 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004107}
4108
4109
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004110ElementsAccessor* JSObject::GetElementsAccessor() {
4111 return ElementsAccessor::ForKind(GetElementsKind());
4112}
4113
4114
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004115bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004116 return GetElementsKind() == FAST_ELEMENTS;
4117}
4118
4119
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004120bool JSObject::HasFastDoubleElements() {
4121 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4122}
4123
4124
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004125bool JSObject::HasDictionaryElements() {
4126 return GetElementsKind() == DICTIONARY_ELEMENTS;
4127}
4128
4129
ager@chromium.org3811b432009-10-28 14:53:37 +00004130bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004131 HeapObject* array = elements();
4132 ASSERT(array != NULL);
4133 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004134}
4135
4136
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004137#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4138bool JSObject::HasExternal##name##Elements() { \
4139 HeapObject* array = elements(); \
4140 ASSERT(array != NULL); \
4141 if (!array->IsHeapObject()) \
4142 return false; \
4143 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004144}
4145
4146
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004147EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4148EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4149EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4150EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4151 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4152EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4153EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4154 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4155EXTERNAL_ELEMENTS_CHECK(Float,
4156 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004157EXTERNAL_ELEMENTS_CHECK(Double,
4158 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004159EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004160
4161
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004162bool JSObject::HasNamedInterceptor() {
4163 return map()->has_named_interceptor();
4164}
4165
4166
4167bool JSObject::HasIndexedInterceptor() {
4168 return map()->has_indexed_interceptor();
4169}
4170
4171
ager@chromium.org5c838252010-02-19 08:53:10 +00004172bool JSObject::AllowsSetElementsLength() {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004173 bool result = elements()->IsFixedArray() ||
4174 elements()->IsFixedDoubleArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004175 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00004176 return result;
4177}
4178
4179
lrn@chromium.org303ada72010-10-27 09:33:13 +00004180MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004181 ASSERT(HasFastElements());
4182 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004183 Isolate* isolate = GetIsolate();
4184 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004185 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004186 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4187 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004188 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4189 return maybe_writable_elems;
4190 }
4191 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004192 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004193 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004194 return writable_elems;
4195}
4196
4197
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004198StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004199 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004200 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004201}
4202
4203
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004204NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004205 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004206 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004207}
4208
4209
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004210bool String::IsHashFieldComputed(uint32_t field) {
4211 return (field & kHashNotComputedMask) == 0;
4212}
4213
4214
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004215bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004216 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004217}
4218
4219
4220uint32_t String::Hash() {
4221 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004222 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004223 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004224 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004225 return ComputeAndSetHash();
4226}
4227
4228
ager@chromium.org7c537e22008-10-16 08:43:32 +00004229StringHasher::StringHasher(int length)
4230 : length_(length),
4231 raw_running_hash_(0),
4232 array_index_(0),
4233 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4234 is_first_char_(true),
4235 is_valid_(true) { }
4236
4237
4238bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004239 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004240}
4241
4242
4243void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004244 // Use the Jenkins one-at-a-time hash function to update the hash
4245 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004246 raw_running_hash_ += c;
4247 raw_running_hash_ += (raw_running_hash_ << 10);
4248 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004249 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004250 if (is_array_index_) {
4251 if (c < '0' || c > '9') {
4252 is_array_index_ = false;
4253 } else {
4254 int d = c - '0';
4255 if (is_first_char_) {
4256 is_first_char_ = false;
4257 if (c == '0' && length_ > 1) {
4258 is_array_index_ = false;
4259 return;
4260 }
4261 }
4262 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4263 is_array_index_ = false;
4264 } else {
4265 array_index_ = array_index_ * 10 + d;
4266 }
4267 }
4268 }
4269}
4270
4271
4272void StringHasher::AddCharacterNoIndex(uc32 c) {
4273 ASSERT(!is_array_index());
4274 raw_running_hash_ += c;
4275 raw_running_hash_ += (raw_running_hash_ << 10);
4276 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4277}
4278
4279
4280uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004281 // Get the calculated raw hash value and do some more bit ops to distribute
4282 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004283 uint32_t result = raw_running_hash_;
4284 result += (result << 3);
4285 result ^= (result >> 11);
4286 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004287 if (result == 0) {
4288 result = 27;
4289 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004290 return result;
4291}
4292
4293
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004294template <typename schar>
4295uint32_t HashSequentialString(const schar* chars, int length) {
4296 StringHasher hasher(length);
4297 if (!hasher.has_trivial_hash()) {
4298 int i;
4299 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4300 hasher.AddCharacter(chars[i]);
4301 }
4302 for (; i < length; i++) {
4303 hasher.AddCharacterNoIndex(chars[i]);
4304 }
4305 }
4306 return hasher.GetHashField();
4307}
4308
4309
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004310bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004311 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004312 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4313 return false;
4314 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004315 return SlowAsArrayIndex(index);
4316}
4317
4318
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004319Object* JSReceiver::GetPrototype() {
4320 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004321}
4322
4323
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004324bool JSReceiver::HasProperty(String* name) {
4325 if (IsJSProxy()) {
4326 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4327 }
4328 return GetPropertyAttribute(name) != ABSENT;
4329}
4330
4331
4332bool JSReceiver::HasLocalProperty(String* name) {
4333 if (IsJSProxy()) {
4334 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4335 }
4336 return GetLocalPropertyAttribute(name) != ABSENT;
4337}
4338
4339
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004340PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004341 return GetPropertyAttributeWithReceiver(this, key);
4342}
4343
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004344// TODO(504): this may be useful in other places too where JSGlobalProxy
4345// is used.
4346Object* JSObject::BypassGlobalProxy() {
4347 if (IsJSGlobalProxy()) {
4348 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004349 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004350 ASSERT(proto->IsJSGlobalObject());
4351 return proto;
4352 }
4353 return this;
4354}
4355
4356
4357bool JSObject::HasHiddenPropertiesObject() {
4358 ASSERT(!IsJSGlobalProxy());
4359 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004360 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004361 false) != ABSENT;
4362}
4363
4364
4365Object* JSObject::GetHiddenPropertiesObject() {
4366 ASSERT(!IsJSGlobalProxy());
4367 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004368 // You can't install a getter on a property indexed by the hidden symbol,
4369 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
4370 // object.
4371 Object* result =
4372 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004373 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00004374 &attributes)->ToObjectUnchecked();
4375 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004376}
4377
4378
lrn@chromium.org303ada72010-10-27 09:33:13 +00004379MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004380 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004381 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004382 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00004383 DONT_ENUM,
4384 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004385}
4386
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004387
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004388bool JSObject::HasHiddenProperties() {
4389 return !GetHiddenProperties(OMIT_CREATION)->ToObjectChecked()->IsUndefined();
4390}
4391
4392
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004393bool JSObject::HasElement(uint32_t index) {
4394 return HasElementWithReceiver(this, index);
4395}
4396
4397
4398bool AccessorInfo::all_can_read() {
4399 return BooleanBit::get(flag(), kAllCanReadBit);
4400}
4401
4402
4403void AccessorInfo::set_all_can_read(bool value) {
4404 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4405}
4406
4407
4408bool AccessorInfo::all_can_write() {
4409 return BooleanBit::get(flag(), kAllCanWriteBit);
4410}
4411
4412
4413void AccessorInfo::set_all_can_write(bool value) {
4414 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4415}
4416
4417
ager@chromium.org870a0b62008-11-04 11:43:05 +00004418bool AccessorInfo::prohibits_overwriting() {
4419 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4420}
4421
4422
4423void AccessorInfo::set_prohibits_overwriting(bool value) {
4424 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4425}
4426
4427
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004428PropertyAttributes AccessorInfo::property_attributes() {
4429 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4430}
4431
4432
4433void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
4434 ASSERT(AttributesField::is_valid(attributes));
4435 int rest_value = flag()->value() & ~AttributesField::mask();
4436 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
4437}
4438
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004439
4440template<typename Shape, typename Key>
4441void Dictionary<Shape, Key>::SetEntry(int entry,
4442 Object* key,
4443 Object* value) {
4444 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4445}
4446
4447
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004448template<typename Shape, typename Key>
4449void Dictionary<Shape, Key>::SetEntry(int entry,
4450 Object* key,
4451 Object* value,
4452 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004453 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004454 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004455 AssertNoAllocation no_gc;
4456 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004457 FixedArray::set(index, key, mode);
4458 FixedArray::set(index+1, value, mode);
4459 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004460}
4461
4462
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004463bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4464 ASSERT(other->IsNumber());
4465 return key == static_cast<uint32_t>(other->Number());
4466}
4467
4468
4469uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4470 return ComputeIntegerHash(key);
4471}
4472
4473
4474uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4475 ASSERT(other->IsNumber());
4476 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4477}
4478
4479
4480MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4481 return Isolate::Current()->heap()->NumberFromUint32(key);
4482}
4483
4484
4485bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4486 // We know that all entries in a hash table had their hash keys created.
4487 // Use that knowledge to have fast failure.
4488 if (key->Hash() != String::cast(other)->Hash()) return false;
4489 return key->Equals(String::cast(other));
4490}
4491
4492
4493uint32_t StringDictionaryShape::Hash(String* key) {
4494 return key->Hash();
4495}
4496
4497
4498uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4499 return String::cast(other)->Hash();
4500}
4501
4502
4503MaybeObject* StringDictionaryShape::AsObject(String* key) {
4504 return key;
4505}
4506
4507
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004508bool ObjectHashTableShape::IsMatch(JSObject* key, Object* other) {
4509 return key == JSObject::cast(other);
4510}
4511
4512
4513uint32_t ObjectHashTableShape::Hash(JSObject* key) {
4514 MaybeObject* maybe_hash = key->GetIdentityHash(JSObject::OMIT_CREATION);
4515 ASSERT(!maybe_hash->IsFailure());
4516 return Smi::cast(maybe_hash->ToObjectUnchecked())->value();
4517}
4518
4519
4520uint32_t ObjectHashTableShape::HashForObject(JSObject* key, Object* other) {
4521 MaybeObject* maybe_hash = JSObject::cast(other)->GetIdentityHash(
4522 JSObject::OMIT_CREATION);
4523 ASSERT(!maybe_hash->IsFailure());
4524 return Smi::cast(maybe_hash->ToObjectUnchecked())->value();
4525}
4526
4527
4528MaybeObject* ObjectHashTableShape::AsObject(JSObject* key) {
4529 return key;
4530}
4531
4532
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004533void ObjectHashTable::RemoveEntry(int entry) {
4534 RemoveEntry(entry, GetHeap());
4535}
4536
4537
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004538void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004539 // No write barrier is needed since empty_fixed_array is not in new space.
4540 // Please note this function is used during marking:
4541 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004542 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4543 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004544}
4545
4546
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004547void JSArray::EnsureSize(int required_size) {
4548 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004549 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004550 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4551 if (elts->length() < required_size) {
4552 // Doubling in size would be overkill, but leave some slack to avoid
4553 // constantly growing.
4554 Expand(required_size + (required_size >> 3));
4555 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004556 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004557 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4558 // Expand will allocate a new backing store in new space even if the size
4559 // we asked for isn't larger than what we had before.
4560 Expand(required_size);
4561 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004562}
4563
4564
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004565void JSArray::set_length(Smi* length) {
4566 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4567}
4568
4569
ager@chromium.org7c537e22008-10-16 08:43:32 +00004570void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004571 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004572 set_elements(storage);
4573}
4574
4575
lrn@chromium.org303ada72010-10-27 09:33:13 +00004576MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004577 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004578 return GetHeap()->CopyFixedArray(this);
4579}
4580
4581
4582Relocatable::Relocatable(Isolate* isolate) {
4583 ASSERT(isolate == Isolate::Current());
4584 isolate_ = isolate;
4585 prev_ = isolate->relocatable_top();
4586 isolate->set_relocatable_top(this);
4587}
4588
4589
4590Relocatable::~Relocatable() {
4591 ASSERT(isolate_ == Isolate::Current());
4592 ASSERT_EQ(isolate_->relocatable_top(), this);
4593 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004594}
4595
4596
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004597int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4598 return map->instance_size();
4599}
4600
4601
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004602void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004603 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004604 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004605}
4606
4607
4608template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004609void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004610 StaticVisitor::VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004611 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004612}
4613
4614
4615void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4616 typedef v8::String::ExternalAsciiStringResource Resource;
4617 v->VisitExternalAsciiString(
4618 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4619}
4620
4621
4622template<typename StaticVisitor>
4623void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4624 typedef v8::String::ExternalAsciiStringResource Resource;
4625 StaticVisitor::VisitExternalAsciiString(
4626 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4627}
4628
4629
4630void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4631 typedef v8::String::ExternalStringResource Resource;
4632 v->VisitExternalTwoByteString(
4633 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4634}
4635
4636
4637template<typename StaticVisitor>
4638void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4639 typedef v8::String::ExternalStringResource Resource;
4640 StaticVisitor::VisitExternalTwoByteString(
4641 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4642}
4643
4644#define SLOT_ADDR(obj, offset) \
4645 reinterpret_cast<Object**>((obj)->address() + offset)
4646
4647template<int start_offset, int end_offset, int size>
4648void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4649 HeapObject* obj,
4650 ObjectVisitor* v) {
4651 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4652}
4653
4654
4655template<int start_offset>
4656void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4657 int object_size,
4658 ObjectVisitor* v) {
4659 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4660}
4661
4662#undef SLOT_ADDR
4663
4664
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004665#undef CAST_ACCESSOR
4666#undef INT_ACCESSORS
4667#undef SMI_ACCESSORS
4668#undef ACCESSORS
4669#undef FIELD_ADDR
4670#undef READ_FIELD
4671#undef WRITE_FIELD
4672#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004673#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004674#undef READ_MEMADDR_FIELD
4675#undef WRITE_MEMADDR_FIELD
4676#undef READ_DOUBLE_FIELD
4677#undef WRITE_DOUBLE_FIELD
4678#undef READ_INT_FIELD
4679#undef WRITE_INT_FIELD
4680#undef READ_SHORT_FIELD
4681#undef WRITE_SHORT_FIELD
4682#undef READ_BYTE_FIELD
4683#undef WRITE_BYTE_FIELD
4684
4685
4686} } // namespace v8::internal
4687
4688#endif // V8_OBJECTS_INL_H_