blob: dc3aa466693f8cf7557fbcc3218171f9807b89d5 [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"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000046#include "store-buffer.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000047#include "v8memory.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000048
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000049#include "incremental-marking.h"
50
kasperl@chromium.org71affb52009-05-26 05:44:31 +000051namespace v8 {
52namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000053
54PropertyDetails::PropertyDetails(Smi* smi) {
55 value_ = smi->value();
56}
57
58
59Smi* PropertyDetails::AsSmi() {
60 return Smi::FromInt(value_);
61}
62
63
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000064PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000065 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000066 return PropertyDetails(smi);
67}
68
69
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000070#define TYPE_CHECKER(type, instancetype) \
71 bool Object::Is##type() { \
72 return Object::IsHeapObject() && \
73 HeapObject::cast(this)->map()->instance_type() == instancetype; \
74 }
75
76
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000077#define CAST_ACCESSOR(type) \
78 type* type::cast(Object* object) { \
79 ASSERT(object->Is##type()); \
80 return reinterpret_cast<type*>(object); \
81 }
82
83
84#define INT_ACCESSORS(holder, name, offset) \
85 int holder::name() { return READ_INT_FIELD(this, offset); } \
86 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
87
88
89#define ACCESSORS(holder, name, type, offset) \
90 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000091 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000092 WRITE_FIELD(this, offset, value); \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000093 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000094 }
95
96
97#define SMI_ACCESSORS(holder, name, offset) \
98 int holder::name() { \
99 Object* value = READ_FIELD(this, offset); \
100 return Smi::cast(value)->value(); \
101 } \
102 void holder::set_##name(int value) { \
103 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
104 }
105
106
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000107#define BOOL_GETTER(holder, field, name, offset) \
108 bool holder::name() { \
109 return BooleanBit::get(field(), offset); \
110 } \
111
112
113#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000114 bool holder::name() { \
115 return BooleanBit::get(field(), offset); \
116 } \
117 void holder::set_##name(bool value) { \
118 set_##field(BooleanBit::set(field(), offset, value)); \
119 }
120
121
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000122bool Object::IsFixedArrayBase() {
123 return IsFixedArray() || IsFixedDoubleArray();
124}
125
126
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000127bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
128 // There is a constraint on the object; check.
129 if (!this->IsJSObject()) return false;
130 // Fetch the constructor function of the object.
131 Object* cons_obj = JSObject::cast(this)->map()->constructor();
132 if (!cons_obj->IsJSFunction()) return false;
133 JSFunction* fun = JSFunction::cast(cons_obj);
134 // Iterate through the chain of inheriting function templates to
135 // see if the required one occurs.
136 for (Object* type = fun->shared()->function_data();
137 type->IsFunctionTemplateInfo();
138 type = FunctionTemplateInfo::cast(type)->parent_template()) {
139 if (type == expected) return true;
140 }
141 // Didn't find the required type in the inheritance chain.
142 return false;
143}
144
145
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000146bool Object::IsSmi() {
147 return HAS_SMI_TAG(this);
148}
149
150
151bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000152 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000153}
154
155
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000156bool Object::NonFailureIsHeapObject() {
157 ASSERT(!this->IsFailure());
158 return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0;
159}
160
161
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000162TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000163
164
165bool Object::IsString() {
166 return Object::IsHeapObject()
167 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
168}
169
170
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000171bool Object::IsSpecObject() {
172 return Object::IsHeapObject()
173 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
174}
175
176
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000177bool Object::IsSpecFunction() {
178 if (!Object::IsHeapObject()) return false;
179 InstanceType type = HeapObject::cast(this)->map()->instance_type();
180 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
181}
182
183
ager@chromium.org870a0b62008-11-04 11:43:05 +0000184bool Object::IsSymbol() {
185 if (!this->IsHeapObject()) return false;
186 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000187 // Because the symbol tag is non-zero and no non-string types have the
188 // symbol bit set we can test for symbols with a very simple test
189 // operation.
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000190 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000191 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
192 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000193}
194
195
196bool Object::IsConsString() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000197 if (!IsString()) return false;
198 return StringShape(String::cast(this)).IsCons();
199}
200
201
202bool Object::IsSlicedString() {
203 if (!IsString()) return false;
204 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000205}
206
207
ager@chromium.org870a0b62008-11-04 11:43:05 +0000208bool Object::IsSeqString() {
209 if (!IsString()) return false;
210 return StringShape(String::cast(this)).IsSequential();
211}
212
213
214bool Object::IsSeqAsciiString() {
215 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000216 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000217 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000218}
219
220
221bool Object::IsSeqTwoByteString() {
222 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000223 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000224 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000225}
226
227
228bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000229 if (!IsString()) return false;
230 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000231}
232
233
234bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000235 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000236 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000237 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000238}
239
240
241bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000242 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000243 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000244 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000245}
246
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000247bool Object::HasValidElements() {
248 // Dictionary is covered under FixedArray.
249 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
250}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000251
ager@chromium.org870a0b62008-11-04 11:43:05 +0000252StringShape::StringShape(String* str)
253 : type_(str->map()->instance_type()) {
254 set_valid();
255 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000256}
257
258
ager@chromium.org870a0b62008-11-04 11:43:05 +0000259StringShape::StringShape(Map* map)
260 : type_(map->instance_type()) {
261 set_valid();
262 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000263}
264
265
ager@chromium.org870a0b62008-11-04 11:43:05 +0000266StringShape::StringShape(InstanceType t)
267 : type_(static_cast<uint32_t>(t)) {
268 set_valid();
269 ASSERT((type_ & kIsNotStringMask) == kStringTag);
270}
271
272
273bool StringShape::IsSymbol() {
274 ASSERT(valid());
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000275 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000276 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000277}
278
279
ager@chromium.org5ec48922009-05-05 07:25:34 +0000280bool String::IsAsciiRepresentation() {
281 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000282 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000283}
284
285
ager@chromium.org5ec48922009-05-05 07:25:34 +0000286bool String::IsTwoByteRepresentation() {
287 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000288 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000289}
290
291
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000292bool String::IsAsciiRepresentationUnderneath() {
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 true;
300 case kTwoByteStringTag:
301 return false;
302 default: // Cons or sliced string. Need to go deeper.
303 return GetUnderlying()->IsAsciiRepresentation();
304 }
305}
306
307
308bool String::IsTwoByteRepresentationUnderneath() {
309 uint32_t type = map()->instance_type();
310 STATIC_ASSERT(kIsIndirectStringTag != 0);
311 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
312 ASSERT(IsFlat());
313 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
314 case kAsciiStringTag:
315 return false;
316 case kTwoByteStringTag:
317 return true;
318 default: // Cons or sliced string. Need to go deeper.
319 return GetUnderlying()->IsTwoByteRepresentation();
320 }
321}
322
323
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000324bool String::HasOnlyAsciiChars() {
325 uint32_t type = map()->instance_type();
326 return (type & kStringEncodingMask) == kAsciiStringTag ||
327 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000328}
329
330
ager@chromium.org870a0b62008-11-04 11:43:05 +0000331bool StringShape::IsCons() {
332 return (type_ & kStringRepresentationMask) == kConsStringTag;
333}
334
335
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000336bool StringShape::IsSliced() {
337 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
338}
339
340
341bool StringShape::IsIndirect() {
342 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
343}
344
345
ager@chromium.org870a0b62008-11-04 11:43:05 +0000346bool StringShape::IsExternal() {
347 return (type_ & kStringRepresentationMask) == kExternalStringTag;
348}
349
350
351bool StringShape::IsSequential() {
352 return (type_ & kStringRepresentationMask) == kSeqStringTag;
353}
354
355
356StringRepresentationTag StringShape::representation_tag() {
357 uint32_t tag = (type_ & kStringRepresentationMask);
358 return static_cast<StringRepresentationTag>(tag);
359}
360
361
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000362uint32_t StringShape::encoding_tag() {
363 return type_ & kStringEncodingMask;
364}
365
366
ager@chromium.org870a0b62008-11-04 11:43:05 +0000367uint32_t StringShape::full_representation_tag() {
368 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
369}
370
371
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000372STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
373 Internals::kFullStringRepresentationMask);
374
375
ager@chromium.org870a0b62008-11-04 11:43:05 +0000376bool StringShape::IsSequentialAscii() {
377 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
378}
379
380
381bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000382 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000383}
384
385
386bool StringShape::IsExternalAscii() {
387 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
388}
389
390
391bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000392 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000393}
394
395
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000396STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
397 Internals::kExternalTwoByteRepresentationTag);
398
399
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000400uc32 FlatStringReader::Get(int index) {
401 ASSERT(0 <= index && index <= length_);
402 if (is_ascii_) {
403 return static_cast<const byte*>(start_)[index];
404 } else {
405 return static_cast<const uc16*>(start_)[index];
406 }
407}
408
409
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000410bool Object::IsNumber() {
411 return IsSmi() || IsHeapNumber();
412}
413
414
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000415TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
416TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000417
418
419bool Object::IsFiller() {
420 if (!Object::IsHeapObject()) return false;
421 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
422 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
423}
424
425
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000426TYPE_CHECKER(ExternalPixelArray, EXTERNAL_PIXEL_ARRAY_TYPE)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000427
428
ager@chromium.org3811b432009-10-28 14:53:37 +0000429bool Object::IsExternalArray() {
430 if (!Object::IsHeapObject())
431 return false;
432 InstanceType instance_type =
433 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000434 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
435 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000436}
437
438
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000439TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE)
440TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
441TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE)
442TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
443TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE)
444TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
445TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE)
446TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000447
448
lrn@chromium.org303ada72010-10-27 09:33:13 +0000449bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000450 return HAS_FAILURE_TAG(this);
451}
452
453
lrn@chromium.org303ada72010-10-27 09:33:13 +0000454bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000455 return HAS_FAILURE_TAG(this)
456 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
457}
458
459
lrn@chromium.org303ada72010-10-27 09:33:13 +0000460bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000461 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000462 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000463}
464
465
lrn@chromium.org303ada72010-10-27 09:33:13 +0000466bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000467 return this == Failure::Exception();
468}
469
470
lrn@chromium.org303ada72010-10-27 09:33:13 +0000471bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000472 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000473}
474
475
476Failure* Failure::cast(MaybeObject* obj) {
477 ASSERT(HAS_FAILURE_TAG(obj));
478 return reinterpret_cast<Failure*>(obj);
479}
480
481
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000482bool Object::IsJSReceiver() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000483 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000484 return IsHeapObject() &&
485 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
486}
487
488
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000489bool Object::IsJSObject() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000490 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
491 return IsHeapObject() &&
492 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000493}
494
495
496bool Object::IsJSProxy() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000497 if (!Object::IsHeapObject()) return false;
498 InstanceType type = HeapObject::cast(this)->map()->instance_type();
499 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000500}
501
502
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000503TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
504TYPE_CHECKER(JSSet, JS_SET_TYPE)
505TYPE_CHECKER(JSMap, JS_MAP_TYPE)
506TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
507TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
508TYPE_CHECKER(Map, MAP_TYPE)
509TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
510TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000511
512
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000513bool Object::IsDescriptorArray() {
514 return IsFixedArray();
515}
516
517
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000518bool Object::IsDeoptimizationInputData() {
519 // Must be a fixed array.
520 if (!IsFixedArray()) return false;
521
522 // There's no sure way to detect the difference between a fixed array and
523 // a deoptimization data array. Since this is used for asserts we can
524 // check that the length is zero or else the fixed size plus a multiple of
525 // the entry size.
526 int length = FixedArray::cast(this)->length();
527 if (length == 0) return true;
528
529 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
530 return length >= 0 &&
531 length % DeoptimizationInputData::kDeoptEntrySize == 0;
532}
533
534
535bool Object::IsDeoptimizationOutputData() {
536 if (!IsFixedArray()) return false;
537 // There's actually no way to see the difference between a fixed array and
538 // a deoptimization data array. Since this is used for asserts we can check
539 // that the length is plausible though.
540 if (FixedArray::cast(this)->length() % 2 != 0) return false;
541 return true;
542}
543
544
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000545bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000546 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000547 Map* map = HeapObject::cast(this)->map();
548 Heap* heap = map->GetHeap();
549 return (map == heap->function_context_map() ||
550 map == heap->catch_context_map() ||
551 map == heap->with_context_map() ||
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000552 map == heap->global_context_map() ||
553 map == heap->block_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000554 }
555 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000556}
557
558
559bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000560 return Object::IsHeapObject() &&
561 HeapObject::cast(this)->map() ==
562 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000563}
564
565
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000566bool Object::IsSerializedScopeInfo() {
567 return Object::IsHeapObject() &&
568 HeapObject::cast(this)->map() ==
569 HeapObject::cast(this)->GetHeap()->serialized_scope_info_map();
570}
571
572
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000573TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000574
575
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000576template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000577 return obj->IsJSFunction();
578}
579
580
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000581TYPE_CHECKER(Code, CODE_TYPE)
582TYPE_CHECKER(Oddball, ODDBALL_TYPE)
583TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
584TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
585TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
586TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000587
588
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000589bool Object::IsStringWrapper() {
590 return IsJSValue() && JSValue::cast(this)->value()->IsString();
591}
592
593
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000594TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000595
596
597bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000598 return IsOddball() &&
599 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000600}
601
602
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000603TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
604TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000605
606
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000607template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000608 return obj->IsJSArray();
609}
610
611
612bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000613 return Object::IsHeapObject() &&
614 HeapObject::cast(this)->map() ==
615 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000616}
617
618
619bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000620 return IsHashTable() &&
621 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000622}
623
624
625bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000626 return IsHashTable() && this ==
627 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000628}
629
630
ager@chromium.orgac091b72010-05-05 07:34:42 +0000631bool Object::IsJSFunctionResultCache() {
632 if (!IsFixedArray()) return false;
633 FixedArray* self = FixedArray::cast(this);
634 int length = self->length();
635 if (length < JSFunctionResultCache::kEntriesIndex) return false;
636 if ((length - JSFunctionResultCache::kEntriesIndex)
637 % JSFunctionResultCache::kEntrySize != 0) {
638 return false;
639 }
640#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000641 if (FLAG_verify_heap) {
642 reinterpret_cast<JSFunctionResultCache*>(this)->
643 JSFunctionResultCacheVerify();
644 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000645#endif
646 return true;
647}
648
649
ricow@chromium.org65fae842010-08-25 15:26:24 +0000650bool Object::IsNormalizedMapCache() {
651 if (!IsFixedArray()) return false;
652 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
653 return false;
654 }
655#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000656 if (FLAG_verify_heap) {
657 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
658 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000659#endif
660 return true;
661}
662
663
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000664bool Object::IsCompilationCacheTable() {
665 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000666}
667
668
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000669bool Object::IsCodeCacheHashTable() {
670 return IsHashTable();
671}
672
673
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000674bool Object::IsPolymorphicCodeCacheHashTable() {
675 return IsHashTable();
676}
677
678
ager@chromium.org236ad962008-09-25 09:45:57 +0000679bool Object::IsMapCache() {
680 return IsHashTable();
681}
682
683
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000684bool Object::IsPrimitive() {
685 return IsOddball() || IsNumber() || IsString();
686}
687
688
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000689bool Object::IsJSGlobalProxy() {
690 bool result = IsHeapObject() &&
691 (HeapObject::cast(this)->map()->instance_type() ==
692 JS_GLOBAL_PROXY_TYPE);
693 ASSERT(!result || IsAccessCheckNeeded());
694 return result;
695}
696
697
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000698bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000699 if (!IsHeapObject()) return false;
700
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000701 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000702 return type == JS_GLOBAL_OBJECT_TYPE ||
703 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000704}
705
706
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000707TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
708TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000709
710
711bool Object::IsUndetectableObject() {
712 return IsHeapObject()
713 && HeapObject::cast(this)->map()->is_undetectable();
714}
715
716
717bool Object::IsAccessCheckNeeded() {
718 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000719 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000720}
721
722
723bool Object::IsStruct() {
724 if (!IsHeapObject()) return false;
725 switch (HeapObject::cast(this)->map()->instance_type()) {
726#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
727 STRUCT_LIST(MAKE_STRUCT_CASE)
728#undef MAKE_STRUCT_CASE
729 default: return false;
730 }
731}
732
733
734#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
735 bool Object::Is##Name() { \
736 return Object::IsHeapObject() \
737 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
738 }
739 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
740#undef MAKE_STRUCT_PREDICATE
741
742
743bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000744 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000745}
746
747
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000748bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000749 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
750}
751
752
753bool Object::IsTheHole() {
754 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000755}
756
757
758bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000759 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000760}
761
762
763bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000764 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000765}
766
767
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000768bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000769 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000770}
771
772
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000773double Object::Number() {
774 ASSERT(IsNumber());
775 return IsSmi()
776 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
777 : reinterpret_cast<HeapNumber*>(this)->value();
778}
779
780
lrn@chromium.org303ada72010-10-27 09:33:13 +0000781MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000782 if (IsSmi()) return this;
783 if (IsHeapNumber()) {
784 double value = HeapNumber::cast(this)->value();
785 int int_value = FastD2I(value);
786 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
787 return Smi::FromInt(int_value);
788 }
789 }
790 return Failure::Exception();
791}
792
793
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000794bool Object::HasSpecificClassOf(String* name) {
795 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
796}
797
798
lrn@chromium.org303ada72010-10-27 09:33:13 +0000799MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000800 // GetElement can trigger a getter which can cause allocation.
801 // This was not always the case. This ASSERT is here to catch
802 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000803 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000804 return GetElementWithReceiver(this, index);
805}
806
807
lrn@chromium.org303ada72010-10-27 09:33:13 +0000808Object* Object::GetElementNoExceptionThrown(uint32_t index) {
809 MaybeObject* maybe = GetElementWithReceiver(this, index);
810 ASSERT(!maybe->IsFailure());
811 Object* result = NULL; // Initialization to please compiler.
812 maybe->ToObject(&result);
813 return result;
814}
815
816
817MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000818 PropertyAttributes attributes;
819 return GetPropertyWithReceiver(this, key, &attributes);
820}
821
822
lrn@chromium.org303ada72010-10-27 09:33:13 +0000823MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000824 return GetPropertyWithReceiver(this, key, attributes);
825}
826
827
828#define FIELD_ADDR(p, offset) \
829 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
830
831#define READ_FIELD(p, offset) \
832 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
833
834#define WRITE_FIELD(p, offset, value) \
835 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
836
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000837#define WRITE_BARRIER(heap, object, offset, value) \
838 heap->incremental_marking()->RecordWrite( \
839 object, HeapObject::RawField(object, offset), value); \
840 if (heap->InNewSpace(value)) { \
841 heap->RecordWrite(object->address(), offset); \
842 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000843
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000844#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
845 if (mode == UPDATE_WRITE_BARRIER) { \
846 heap->incremental_marking()->RecordWrite( \
847 object, HeapObject::RawField(object, offset), value); \
848 if (heap->InNewSpace(value)) { \
849 heap->RecordWrite(object->address(), offset); \
850 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000851 }
852
lrn@chromium.org7516f052011-03-30 08:52:27 +0000853#ifndef V8_TARGET_ARCH_MIPS
854 #define READ_DOUBLE_FIELD(p, offset) \
855 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
856#else // V8_TARGET_ARCH_MIPS
857 // Prevent gcc from using load-double (mips ldc1) on (possibly)
858 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000859 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000860 union conversion {
861 double d;
862 uint32_t u[2];
863 } c;
864 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
865 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
866 return c.d;
867 }
868 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
869#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000870
lrn@chromium.org7516f052011-03-30 08:52:27 +0000871#ifndef V8_TARGET_ARCH_MIPS
872 #define WRITE_DOUBLE_FIELD(p, offset, value) \
873 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
874#else // V8_TARGET_ARCH_MIPS
875 // Prevent gcc from using store-double (mips sdc1) on (possibly)
876 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000877 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000878 double value) {
879 union conversion {
880 double d;
881 uint32_t u[2];
882 } c;
883 c.d = value;
884 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
885 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
886 }
887 #define WRITE_DOUBLE_FIELD(p, offset, value) \
888 write_double_field(p, offset, value)
889#endif // V8_TARGET_ARCH_MIPS
890
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000891
892#define READ_INT_FIELD(p, offset) \
893 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
894
895#define WRITE_INT_FIELD(p, offset, value) \
896 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
897
ager@chromium.org3e875802009-06-29 08:26:34 +0000898#define READ_INTPTR_FIELD(p, offset) \
899 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
900
901#define WRITE_INTPTR_FIELD(p, offset, value) \
902 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
903
ager@chromium.org7c537e22008-10-16 08:43:32 +0000904#define READ_UINT32_FIELD(p, offset) \
905 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
906
907#define WRITE_UINT32_FIELD(p, offset, value) \
908 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
909
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000910#define READ_SHORT_FIELD(p, offset) \
911 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
912
913#define WRITE_SHORT_FIELD(p, offset, value) \
914 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
915
916#define READ_BYTE_FIELD(p, offset) \
917 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
918
919#define WRITE_BYTE_FIELD(p, offset, value) \
920 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
921
922
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000923Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
924 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000925}
926
927
928int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000929 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000930}
931
932
933Smi* Smi::FromInt(int value) {
934 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000935 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000936 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000937 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000938 return reinterpret_cast<Smi*>(tagged_value);
939}
940
941
942Smi* Smi::FromIntptr(intptr_t value) {
943 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000944 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
945 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000946}
947
948
949Failure::Type Failure::type() const {
950 return static_cast<Type>(value() & kFailureTypeTagMask);
951}
952
953
954bool Failure::IsInternalError() const {
955 return type() == INTERNAL_ERROR;
956}
957
958
959bool Failure::IsOutOfMemoryException() const {
960 return type() == OUT_OF_MEMORY_EXCEPTION;
961}
962
963
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000964AllocationSpace Failure::allocation_space() const {
965 ASSERT_EQ(RETRY_AFTER_GC, type());
966 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
967 & kSpaceTagMask);
968}
969
970
971Failure* Failure::InternalError() {
972 return Construct(INTERNAL_ERROR);
973}
974
975
976Failure* Failure::Exception() {
977 return Construct(EXCEPTION);
978}
979
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000980
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000981Failure* Failure::OutOfMemoryException() {
982 return Construct(OUT_OF_MEMORY_EXCEPTION);
983}
984
985
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000986intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000987 return static_cast<intptr_t>(
988 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000989}
990
991
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000992Failure* Failure::RetryAfterGC() {
993 return RetryAfterGC(NEW_SPACE);
994}
995
996
997Failure* Failure::RetryAfterGC(AllocationSpace space) {
998 ASSERT((space & ~kSpaceTagMask) == 0);
999 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001000}
1001
1002
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001003Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001004 uintptr_t info =
1005 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001006 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001007 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001008}
1009
1010
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001011bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001012#ifdef DEBUG
1013 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1014#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001015
1016#ifdef V8_TARGET_ARCH_X64
1017 // To be representable as a long smi, the value must be a 32-bit integer.
1018 bool result = (value == static_cast<int32_t>(value));
1019#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001020 // To be representable as an tagged small integer, the two
1021 // most-significant bits of 'value' must be either 00 or 11 due to
1022 // sign-extension. To check this we add 01 to the two
1023 // most-significant bits, and check if the most-significant bit is 0
1024 //
1025 // CAUTION: The original code below:
1026 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1027 // may lead to incorrect results according to the C language spec, and
1028 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1029 // compiler may produce undefined results in case of signed integer
1030 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001031 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001032#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001033 ASSERT(result == in_range);
1034 return result;
1035}
1036
1037
kasper.lund7276f142008-07-30 08:49:36 +00001038MapWord MapWord::FromMap(Map* map) {
1039 return MapWord(reinterpret_cast<uintptr_t>(map));
1040}
1041
1042
1043Map* MapWord::ToMap() {
1044 return reinterpret_cast<Map*>(value_);
1045}
1046
1047
1048bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001049 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001050}
1051
1052
1053MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001054 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1055 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001056}
1057
1058
1059HeapObject* MapWord::ToForwardingAddress() {
1060 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001061 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001062}
1063
1064
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001065#ifdef DEBUG
1066void HeapObject::VerifyObjectField(int offset) {
1067 VerifyPointer(READ_FIELD(this, offset));
1068}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001069
1070void HeapObject::VerifySmiField(int offset) {
1071 ASSERT(READ_FIELD(this, offset)->IsSmi());
1072}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001073#endif
1074
1075
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001076Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001077 Heap* heap =
1078 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1079 ASSERT(heap != NULL);
1080 ASSERT(heap->isolate() == Isolate::Current());
1081 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001082}
1083
1084
1085Isolate* HeapObject::GetIsolate() {
1086 return GetHeap()->isolate();
1087}
1088
1089
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001090Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001091 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001092}
1093
1094
1095void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001096 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001097 if (value != NULL) {
1098 // TODO(1600) We are passing NULL as a slot because maps can never be on
1099 // evacuation candidate.
1100 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1101 }
1102}
1103
1104
1105// Unsafe accessor omitting write barrier.
1106void HeapObject::set_map_unsafe(Map* value) {
1107 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001108}
1109
1110
kasper.lund7276f142008-07-30 08:49:36 +00001111MapWord HeapObject::map_word() {
1112 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1113}
1114
1115
1116void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001117 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001118 // here.
1119 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1120}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001121
1122
1123HeapObject* HeapObject::FromAddress(Address address) {
1124 ASSERT_TAG_ALIGNED(address);
1125 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1126}
1127
1128
1129Address HeapObject::address() {
1130 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1131}
1132
1133
1134int HeapObject::Size() {
1135 return SizeFromMap(map());
1136}
1137
1138
1139void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1140 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1141 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1142}
1143
1144
1145void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1146 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1147}
1148
1149
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001150double HeapNumber::value() {
1151 return READ_DOUBLE_FIELD(this, kValueOffset);
1152}
1153
1154
1155void HeapNumber::set_value(double value) {
1156 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1157}
1158
1159
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001160int HeapNumber::get_exponent() {
1161 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1162 kExponentShift) - kExponentBias;
1163}
1164
1165
1166int HeapNumber::get_sign() {
1167 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1168}
1169
1170
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001171ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001172
1173
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001174FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001175 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001176 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001177}
1178
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001179void JSObject::ValidateSmiOnlyElements() {
1180#if DEBUG
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001181 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001182 Heap* heap = GetHeap();
1183 // Don't use elements, since integrity checks will fail if there
1184 // are filler pointers in the array.
1185 FixedArray* fixed_array =
1186 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
1187 Map* map = fixed_array->map();
1188 // Arrays that have been shifted in place can't be verified.
1189 if (map != heap->raw_unchecked_one_pointer_filler_map() &&
1190 map != heap->raw_unchecked_two_pointer_filler_map() &&
1191 map != heap->free_space_map()) {
1192 for (int i = 0; i < fixed_array->length(); i++) {
1193 Object* current = fixed_array->get(i);
1194 ASSERT(current->IsSmi() || current == heap->the_hole_value());
1195 }
1196 }
1197 }
1198#endif
1199}
1200
1201
1202MaybeObject* JSObject::EnsureCanContainNonSmiElements() {
1203#if DEBUG
1204 ValidateSmiOnlyElements();
1205#endif
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001206 if ((map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS)) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001207 Object* obj;
1208 MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS);
1209 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1210 set_map(Map::cast(obj));
1211 }
1212 return this;
1213}
1214
1215
1216MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
1217 uint32_t count) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001218 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001219 for (uint32_t i = 0; i < count; ++i) {
1220 Object* current = *objects++;
1221 if (!current->IsSmi() && current != GetHeap()->the_hole_value()) {
1222 return EnsureCanContainNonSmiElements();
1223 }
1224 }
1225 }
1226 return this;
1227}
1228
1229
1230MaybeObject* JSObject::EnsureCanContainElements(FixedArray* elements) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001231 Object** objects = reinterpret_cast<Object**>(
1232 FIELD_ADDR(elements, elements->OffsetOfElementAt(0)));
1233 return EnsureCanContainElements(objects, elements->length());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001234}
1235
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001236
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001237void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001238 ASSERT((map()->has_fast_elements() ||
1239 map()->has_fast_smi_only_elements()) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001240 (value->map() == GetHeap()->fixed_array_map() ||
1241 value->map() == GetHeap()->fixed_cow_array_map()));
lrn@chromium.orgd4e9e222011-08-03 12:01:58 +00001242 ASSERT(map()->has_fast_double_elements() ==
1243 value->IsFixedDoubleArray());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001244 ASSERT(value->HasValidElements());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001245#ifdef DEBUG
1246 ValidateSmiOnlyElements();
1247#endif
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001248 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001249 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001250}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001251
1252
1253void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001254 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1255 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001256}
1257
1258
1259void JSObject::initialize_elements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001260 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001261 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1262 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001263}
1264
1265
lrn@chromium.org303ada72010-10-27 09:33:13 +00001266MaybeObject* JSObject::ResetElements() {
1267 Object* obj;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001268 ElementsKind elements_kind = FLAG_smi_only_arrays
1269 ? FAST_SMI_ONLY_ELEMENTS
1270 : FAST_ELEMENTS;
1271 MaybeObject* maybe_obj = GetElementsTransitionMap(elements_kind);
1272 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001273 set_map(Map::cast(obj));
1274 initialize_elements();
1275 return this;
1276}
1277
1278
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001279ACCESSORS(Oddball, to_string, String, kToStringOffset)
1280ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1281
1282
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001283byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001284 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001285}
1286
1287
1288void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001289 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001290}
1291
1292
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001293Object* JSGlobalPropertyCell::value() {
1294 return READ_FIELD(this, kValueOffset);
1295}
1296
1297
1298void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1299 // The write barrier is not used for global property cells.
1300 ASSERT(!val->IsJSGlobalPropertyCell());
1301 WRITE_FIELD(this, kValueOffset, val);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001302 GetHeap()->incremental_marking()->RecordWrite(
1303 this, HeapObject::RawField(this, kValueOffset), val);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001304}
1305
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001306
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001307int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001308 InstanceType type = map()->instance_type();
1309 // Check for the most common kind of JavaScript object before
1310 // falling into the generic switch. This speeds up the internal
1311 // field operations considerably on average.
1312 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1313 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001314 case JS_GLOBAL_PROXY_TYPE:
1315 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001316 case JS_GLOBAL_OBJECT_TYPE:
1317 return JSGlobalObject::kSize;
1318 case JS_BUILTINS_OBJECT_TYPE:
1319 return JSBuiltinsObject::kSize;
1320 case JS_FUNCTION_TYPE:
1321 return JSFunction::kSize;
1322 case JS_VALUE_TYPE:
1323 return JSValue::kSize;
1324 case JS_ARRAY_TYPE:
1325 return JSValue::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001326 case JS_WEAK_MAP_TYPE:
1327 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001328 case JS_REGEXP_TYPE:
1329 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001330 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001331 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001332 case JS_MESSAGE_OBJECT_TYPE:
1333 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001334 default:
1335 UNREACHABLE();
1336 return 0;
1337 }
1338}
1339
1340
1341int JSObject::GetInternalFieldCount() {
1342 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001343 // Make sure to adjust for the number of in-object properties. These
1344 // properties do contribute to the size, but are not internal fields.
1345 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1346 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001347}
1348
1349
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001350int JSObject::GetInternalFieldOffset(int index) {
1351 ASSERT(index < GetInternalFieldCount() && index >= 0);
1352 return GetHeaderSize() + (kPointerSize * index);
1353}
1354
1355
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001356Object* JSObject::GetInternalField(int index) {
1357 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001358 // Internal objects do follow immediately after the header, whereas in-object
1359 // properties are at the end of the object. Therefore there is no need
1360 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001361 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1362}
1363
1364
1365void JSObject::SetInternalField(int index, Object* value) {
1366 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001367 // Internal objects do follow immediately after the header, whereas in-object
1368 // properties are at the end of the object. Therefore there is no need
1369 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001370 int offset = GetHeaderSize() + (kPointerSize * index);
1371 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001372 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001373}
1374
1375
ager@chromium.org7c537e22008-10-16 08:43:32 +00001376// Access fast-case object properties at index. The use of these routines
1377// is needed to correctly distinguish between properties stored in-object and
1378// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001379Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001380 // Adjust for the number of properties stored in the object.
1381 index -= map()->inobject_properties();
1382 if (index < 0) {
1383 int offset = map()->instance_size() + (index * kPointerSize);
1384 return READ_FIELD(this, offset);
1385 } else {
1386 ASSERT(index < properties()->length());
1387 return properties()->get(index);
1388 }
1389}
1390
1391
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001392Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001393 // Adjust for the number of properties stored in the object.
1394 index -= map()->inobject_properties();
1395 if (index < 0) {
1396 int offset = map()->instance_size() + (index * kPointerSize);
1397 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001398 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001399 } else {
1400 ASSERT(index < properties()->length());
1401 properties()->set(index, value);
1402 }
1403 return value;
1404}
1405
1406
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001407int JSObject::GetInObjectPropertyOffset(int index) {
1408 // Adjust for the number of properties stored in the object.
1409 index -= map()->inobject_properties();
1410 ASSERT(index < 0);
1411 return map()->instance_size() + (index * kPointerSize);
1412}
1413
1414
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001415Object* JSObject::InObjectPropertyAt(int index) {
1416 // Adjust for the number of properties stored in the object.
1417 index -= map()->inobject_properties();
1418 ASSERT(index < 0);
1419 int offset = map()->instance_size() + (index * kPointerSize);
1420 return READ_FIELD(this, offset);
1421}
1422
1423
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001424Object* JSObject::InObjectPropertyAtPut(int index,
1425 Object* value,
1426 WriteBarrierMode mode) {
1427 // Adjust for the number of properties stored in the object.
1428 index -= map()->inobject_properties();
1429 ASSERT(index < 0);
1430 int offset = map()->instance_size() + (index * kPointerSize);
1431 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001432 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001433 return value;
1434}
1435
1436
1437
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001438void JSObject::InitializeBody(Map* map,
1439 Object* pre_allocated_value,
1440 Object* filler_value) {
1441 ASSERT(!filler_value->IsHeapObject() ||
1442 !GetHeap()->InNewSpace(filler_value));
1443 ASSERT(!pre_allocated_value->IsHeapObject() ||
1444 !GetHeap()->InNewSpace(pre_allocated_value));
1445 int size = map->instance_size();
1446 int offset = kHeaderSize;
1447 if (filler_value != pre_allocated_value) {
1448 int pre_allocated = map->pre_allocated_property_fields();
1449 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1450 for (int i = 0; i < pre_allocated; i++) {
1451 WRITE_FIELD(this, offset, pre_allocated_value);
1452 offset += kPointerSize;
1453 }
1454 }
1455 while (offset < size) {
1456 WRITE_FIELD(this, offset, filler_value);
1457 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001458 }
1459}
1460
1461
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001462bool JSObject::HasFastProperties() {
1463 return !properties()->IsDictionary();
1464}
1465
1466
1467int JSObject::MaxFastProperties() {
1468 // Allow extra fast properties if the object has more than
1469 // kMaxFastProperties in-object properties. When this is the case,
1470 // it is very unlikely that the object is being used as a dictionary
1471 // and there is a good chance that allowing more map transitions
1472 // will be worth it.
1473 return Max(map()->inobject_properties(), kMaxFastProperties);
1474}
1475
1476
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001477void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001478 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001479 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001480 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001481 }
1482}
1483
1484
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001485bool Object::ToArrayIndex(uint32_t* index) {
1486 if (IsSmi()) {
1487 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001488 if (value < 0) return false;
1489 *index = value;
1490 return true;
1491 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001492 if (IsHeapNumber()) {
1493 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001494 uint32_t uint_value = static_cast<uint32_t>(value);
1495 if (value == static_cast<double>(uint_value)) {
1496 *index = uint_value;
1497 return true;
1498 }
1499 }
1500 return false;
1501}
1502
1503
1504bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1505 if (!this->IsJSValue()) return false;
1506
1507 JSValue* js_value = JSValue::cast(this);
1508 if (!js_value->value()->IsString()) return false;
1509
1510 String* str = String::cast(js_value->value());
1511 if (index >= (uint32_t)str->length()) return false;
1512
1513 return true;
1514}
1515
1516
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001517FixedArrayBase* FixedArrayBase::cast(Object* object) {
1518 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1519 return reinterpret_cast<FixedArrayBase*>(object);
1520}
1521
1522
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001523Object* FixedArray::get(int index) {
1524 ASSERT(index >= 0 && index < this->length());
1525 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1526}
1527
1528
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001529void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001530 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001531 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001532 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1533 int offset = kHeaderSize + index * kPointerSize;
1534 WRITE_FIELD(this, offset, value);
1535}
1536
1537
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001538void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001539 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001540 ASSERT(index >= 0 && index < this->length());
1541 int offset = kHeaderSize + index * kPointerSize;
1542 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001543 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001544}
1545
1546
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001547inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1548 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1549}
1550
1551
1552inline double FixedDoubleArray::hole_nan_as_double() {
1553 return BitCast<double, uint64_t>(kHoleNanInt64);
1554}
1555
1556
1557inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1558 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1559 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1560 return OS::nan_value();
1561}
1562
1563
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001564double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001565 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1566 map() != HEAP->fixed_array_map());
1567 ASSERT(index >= 0 && index < this->length());
1568 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1569 ASSERT(!is_the_hole_nan(result));
1570 return result;
1571}
1572
1573
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001574MaybeObject* FixedDoubleArray::get(int index) {
1575 if (is_the_hole(index)) {
1576 return GetHeap()->the_hole_value();
1577 } else {
1578 return GetHeap()->NumberFromDouble(get_scalar(index));
1579 }
1580}
1581
1582
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001583void FixedDoubleArray::set(int index, double value) {
1584 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1585 map() != HEAP->fixed_array_map());
1586 int offset = kHeaderSize + index * kDoubleSize;
1587 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1588 WRITE_DOUBLE_FIELD(this, offset, value);
1589}
1590
1591
1592void FixedDoubleArray::set_the_hole(int index) {
1593 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1594 map() != HEAP->fixed_array_map());
1595 int offset = kHeaderSize + index * kDoubleSize;
1596 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1597}
1598
1599
1600bool FixedDoubleArray::is_the_hole(int index) {
1601 int offset = kHeaderSize + index * kDoubleSize;
1602 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1603}
1604
1605
1606void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1607 int old_length = from->length();
1608 ASSERT(old_length < length());
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001609 if (old_length * kDoubleSize >= OS::kMinComplexMemCopy) {
1610 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1611 FIELD_ADDR(from, kHeaderSize),
1612 old_length * kDoubleSize);
1613 } else {
1614 for (int i = 0; i < old_length; ++i) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001615 if (from->is_the_hole(i)) {
1616 set_the_hole(i);
1617 } else {
1618 set(i, from->get_scalar(i));
1619 }
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001620 }
1621 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001622 int offset = kHeaderSize + old_length * kDoubleSize;
1623 for (int current = from->length(); current < length(); ++current) {
1624 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1625 offset += kDoubleSize;
1626 }
1627}
1628
1629
1630void FixedDoubleArray::Initialize(FixedArray* from) {
1631 int old_length = from->length();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001632 ASSERT(old_length <= length());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001633 for (int i = 0; i < old_length; i++) {
1634 Object* hole_or_object = from->get(i);
1635 if (hole_or_object->IsTheHole()) {
1636 set_the_hole(i);
1637 } else {
1638 set(i, hole_or_object->Number());
1639 }
1640 }
1641 int offset = kHeaderSize + old_length * kDoubleSize;
1642 for (int current = from->length(); current < length(); ++current) {
1643 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1644 offset += kDoubleSize;
1645 }
1646}
1647
1648
1649void FixedDoubleArray::Initialize(NumberDictionary* from) {
1650 int offset = kHeaderSize;
1651 for (int current = 0; current < length(); ++current) {
1652 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1653 offset += kDoubleSize;
1654 }
1655 for (int i = 0; i < from->Capacity(); i++) {
1656 Object* key = from->KeyAt(i);
1657 if (key->IsNumber()) {
1658 uint32_t entry = static_cast<uint32_t>(key->Number());
1659 set(entry, from->ValueAt(i)->Number());
1660 }
1661 }
1662}
1663
1664
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001665WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001666 Heap* heap = GetHeap();
1667 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1668 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001669 return UPDATE_WRITE_BARRIER;
1670}
1671
1672
1673void FixedArray::set(int index,
1674 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001675 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001676 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001677 ASSERT(index >= 0 && index < this->length());
1678 int offset = kHeaderSize + index * kPointerSize;
1679 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001680 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001681}
1682
1683
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001684void FixedArray::NoWriteBarrierSet(FixedArray* array,
1685 int index,
1686 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001687 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001688 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001689 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001690 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1691}
1692
1693
1694void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001695 ASSERT(map() != HEAP->fixed_cow_array_map());
1696 set_undefined(GetHeap(), index);
1697}
1698
1699
1700void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001701 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001702 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001703 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001704 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001705}
1706
1707
ager@chromium.org236ad962008-09-25 09:45:57 +00001708void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001709 set_null(GetHeap(), index);
1710}
1711
1712
1713void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001714 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001715 ASSERT(!heap->InNewSpace(heap->null_value()));
1716 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001717}
1718
1719
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001720void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001721 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001722 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001723 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1724 WRITE_FIELD(this,
1725 kHeaderSize + index * kPointerSize,
1726 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001727}
1728
1729
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001730void FixedArray::set_unchecked(int index, Smi* value) {
1731 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1732 int offset = kHeaderSize + index * kPointerSize;
1733 WRITE_FIELD(this, offset, value);
1734}
1735
1736
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001737void FixedArray::set_unchecked(Heap* heap,
1738 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001739 Object* value,
1740 WriteBarrierMode mode) {
1741 int offset = kHeaderSize + index * kPointerSize;
1742 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001743 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001744}
1745
1746
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001747void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001748 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001749 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1750 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001751}
1752
1753
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001754Object** FixedArray::data_start() {
1755 return HeapObject::RawField(this, kHeaderSize);
1756}
1757
1758
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001759bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001760 ASSERT(this->IsSmi() ||
1761 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001762 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001763 return this->IsSmi() || length() <= kFirstIndex;
1764}
1765
1766
1767int DescriptorArray::bit_field3_storage() {
1768 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1769 return Smi::cast(storage)->value();
1770}
1771
1772void DescriptorArray::set_bit_field3_storage(int value) {
1773 ASSERT(!IsEmpty());
1774 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001775}
1776
1777
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001778void DescriptorArray::NoWriteBarrierSwap(FixedArray* array,
1779 int first,
1780 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001781 Object* tmp = array->get(first);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001782 NoWriteBarrierSet(array, first, array->get(second));
1783 NoWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001784}
1785
1786
1787int DescriptorArray::Search(String* name) {
1788 SLOW_ASSERT(IsSortedNoDuplicates());
1789
1790 // Check for empty descriptor array.
1791 int nof = number_of_descriptors();
1792 if (nof == 0) return kNotFound;
1793
1794 // Fast case: do linear search for small arrays.
1795 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001796 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001797 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001798 }
1799
1800 // Slow case: perform binary search.
1801 return BinarySearch(name, 0, nof - 1);
1802}
1803
1804
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001805int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001806 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001807 if (number == DescriptorLookupCache::kAbsent) {
1808 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001809 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001810 }
1811 return number;
1812}
1813
1814
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001815String* DescriptorArray::GetKey(int descriptor_number) {
1816 ASSERT(descriptor_number < number_of_descriptors());
1817 return String::cast(get(ToKeyIndex(descriptor_number)));
1818}
1819
1820
1821Object* DescriptorArray::GetValue(int descriptor_number) {
1822 ASSERT(descriptor_number < number_of_descriptors());
1823 return GetContentArray()->get(ToValueIndex(descriptor_number));
1824}
1825
1826
1827Smi* DescriptorArray::GetDetails(int descriptor_number) {
1828 ASSERT(descriptor_number < number_of_descriptors());
1829 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1830}
1831
1832
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001833PropertyType DescriptorArray::GetType(int descriptor_number) {
1834 ASSERT(descriptor_number < number_of_descriptors());
1835 return PropertyDetails(GetDetails(descriptor_number)).type();
1836}
1837
1838
1839int DescriptorArray::GetFieldIndex(int descriptor_number) {
1840 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1841}
1842
1843
1844JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1845 return JSFunction::cast(GetValue(descriptor_number));
1846}
1847
1848
1849Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1850 ASSERT(GetType(descriptor_number) == CALLBACKS);
1851 return GetValue(descriptor_number);
1852}
1853
1854
1855AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1856 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001857 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
1858 return reinterpret_cast<AccessorDescriptor*>(p->address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001859}
1860
1861
1862bool DescriptorArray::IsProperty(int descriptor_number) {
1863 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1864}
1865
1866
1867bool DescriptorArray::IsTransition(int descriptor_number) {
1868 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001869 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00001870 t == ELEMENTS_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001871}
1872
1873
1874bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1875 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1876}
1877
1878
1879bool DescriptorArray::IsDontEnum(int descriptor_number) {
1880 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1881}
1882
1883
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001884void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1885 desc->Init(GetKey(descriptor_number),
1886 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001887 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001888}
1889
1890
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001891void DescriptorArray::Set(int descriptor_number,
1892 Descriptor* desc,
1893 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001894 // Range check.
1895 ASSERT(descriptor_number < number_of_descriptors());
1896
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001897 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001898 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1899 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001900
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001901 NoWriteBarrierSet(this,
1902 ToKeyIndex(descriptor_number),
1903 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001904 FixedArray* content_array = GetContentArray();
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001905 NoWriteBarrierSet(content_array,
1906 ToValueIndex(descriptor_number),
1907 desc->GetValue());
1908 NoWriteBarrierSet(content_array,
1909 ToDetailsIndex(descriptor_number),
1910 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001911}
1912
1913
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001914void DescriptorArray::CopyFrom(int index,
1915 DescriptorArray* src,
1916 int src_index,
1917 const WhitenessWitness& witness) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001918 Descriptor desc;
1919 src->Get(src_index, &desc);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001920 Set(index, &desc, witness);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001921}
1922
1923
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001924void DescriptorArray::NoWriteBarrierSwapDescriptors(int first, int second) {
1925 NoWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001926 FixedArray* content_array = GetContentArray();
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001927 NoWriteBarrierSwap(content_array,
1928 ToValueIndex(first),
1929 ToValueIndex(second));
1930 NoWriteBarrierSwap(content_array,
1931 ToDetailsIndex(first),
1932 ToDetailsIndex(second));
1933}
1934
1935
1936DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
1937 : marking_(array->GetHeap()->incremental_marking()) {
1938 marking_->EnterNoMarkingScope();
1939 if (array->number_of_descriptors() > 0) {
1940 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
1941 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
1942 }
1943}
1944
1945
1946DescriptorArray::WhitenessWitness::~WhitenessWitness() {
1947 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001948}
1949
1950
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001951template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001952int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
1953 const int kMinCapacity = 32;
1954 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
1955 if (capacity < kMinCapacity) {
1956 capacity = kMinCapacity; // Guarantee min capacity.
1957 }
1958 return capacity;
1959}
1960
1961
1962template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001963int HashTable<Shape, Key>::FindEntry(Key key) {
1964 return FindEntry(GetIsolate(), key);
1965}
1966
1967
1968// Find entry for key otherwise return kNotFound.
1969template<typename Shape, typename Key>
1970int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
1971 uint32_t capacity = Capacity();
1972 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
1973 uint32_t count = 1;
1974 // EnsureCapacity will guarantee the hash table is never full.
1975 while (true) {
1976 Object* element = KeyAt(entry);
1977 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
1978 if (element != isolate->heap()->null_value() &&
1979 Shape::IsMatch(key, element)) return entry;
1980 entry = NextProbe(entry, count++, capacity);
1981 }
1982 return kNotFound;
1983}
1984
1985
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001986bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001987 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001988 if (!max_index_object->IsSmi()) return false;
1989 return 0 !=
1990 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1991}
1992
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001993uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001994 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001995 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001996 if (!max_index_object->IsSmi()) return 0;
1997 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1998 return value >> kRequiresSlowElementsTagSize;
1999}
2000
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002001void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002002 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002003}
2004
2005
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002006// ------------------------------------
2007// Cast operations
2008
2009
2010CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002011CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002012CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002013CAST_ACCESSOR(DeoptimizationInputData)
2014CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002015CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002016CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002017CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002018CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002019CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002020CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002021CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002022CAST_ACCESSOR(String)
2023CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002024CAST_ACCESSOR(SeqAsciiString)
2025CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002026CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002027CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002028CAST_ACCESSOR(ExternalString)
2029CAST_ACCESSOR(ExternalAsciiString)
2030CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002031CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002032CAST_ACCESSOR(JSObject)
2033CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002034CAST_ACCESSOR(HeapObject)
2035CAST_ACCESSOR(HeapNumber)
2036CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002037CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002038CAST_ACCESSOR(SharedFunctionInfo)
2039CAST_ACCESSOR(Map)
2040CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002041CAST_ACCESSOR(GlobalObject)
2042CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002043CAST_ACCESSOR(JSGlobalObject)
2044CAST_ACCESSOR(JSBuiltinsObject)
2045CAST_ACCESSOR(Code)
2046CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002047CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002048CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002049CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002050CAST_ACCESSOR(JSSet)
2051CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002052CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002053CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002054CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002055CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002056CAST_ACCESSOR(ExternalArray)
2057CAST_ACCESSOR(ExternalByteArray)
2058CAST_ACCESSOR(ExternalUnsignedByteArray)
2059CAST_ACCESSOR(ExternalShortArray)
2060CAST_ACCESSOR(ExternalUnsignedShortArray)
2061CAST_ACCESSOR(ExternalIntArray)
2062CAST_ACCESSOR(ExternalUnsignedIntArray)
2063CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002064CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002065CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002066CAST_ACCESSOR(Struct)
2067
2068
2069#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2070 STRUCT_LIST(MAKE_STRUCT_CAST)
2071#undef MAKE_STRUCT_CAST
2072
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002073
2074template <typename Shape, typename Key>
2075HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002076 ASSERT(obj->IsHashTable());
2077 return reinterpret_cast<HashTable*>(obj);
2078}
2079
2080
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002081SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002082SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002083
ager@chromium.orgac091b72010-05-05 07:34:42 +00002084SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002085
2086
2087uint32_t String::hash_field() {
2088 return READ_UINT32_FIELD(this, kHashFieldOffset);
2089}
2090
2091
2092void String::set_hash_field(uint32_t value) {
2093 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002094#if V8_HOST_ARCH_64_BIT
2095 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2096#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002097}
2098
2099
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002100bool String::Equals(String* other) {
2101 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002102 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2103 return false;
2104 }
2105 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002106}
2107
2108
lrn@chromium.org303ada72010-10-27 09:33:13 +00002109MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002110 if (!StringShape(this).IsCons()) return this;
2111 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002112 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002113 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002114}
2115
2116
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002117String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002118 MaybeObject* flat = TryFlatten(pretenure);
2119 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002120 if (!flat->ToObject(&successfully_flattened)) return this;
2121 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002122}
2123
2124
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002125uint16_t String::Get(int index) {
2126 ASSERT(index >= 0 && index < length());
2127 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002128 case kSeqStringTag | kAsciiStringTag:
2129 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2130 case kSeqStringTag | kTwoByteStringTag:
2131 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2132 case kConsStringTag | kAsciiStringTag:
2133 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002134 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002135 case kExternalStringTag | kAsciiStringTag:
2136 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2137 case kExternalStringTag | kTwoByteStringTag:
2138 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002139 case kSlicedStringTag | kAsciiStringTag:
2140 case kSlicedStringTag | kTwoByteStringTag:
2141 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002142 default:
2143 break;
2144 }
2145
2146 UNREACHABLE();
2147 return 0;
2148}
2149
2150
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002151void String::Set(int index, uint16_t value) {
2152 ASSERT(index >= 0 && index < length());
2153 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002154
ager@chromium.org5ec48922009-05-05 07:25:34 +00002155 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002156 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2157 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002158}
2159
2160
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002161bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002162 if (!StringShape(this).IsCons()) return true;
2163 return ConsString::cast(this)->second()->length() == 0;
2164}
2165
2166
2167String* String::GetUnderlying() {
2168 // Giving direct access to underlying string only makes sense if the
2169 // wrapping string is already flattened.
2170 ASSERT(this->IsFlat());
2171 ASSERT(StringShape(this).IsIndirect());
2172 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2173 const int kUnderlyingOffset = SlicedString::kParentOffset;
2174 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002175}
2176
2177
ager@chromium.org7c537e22008-10-16 08:43:32 +00002178uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002179 ASSERT(index >= 0 && index < length());
2180 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2181}
2182
2183
ager@chromium.org7c537e22008-10-16 08:43:32 +00002184void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002185 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2186 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2187 static_cast<byte>(value));
2188}
2189
2190
ager@chromium.org7c537e22008-10-16 08:43:32 +00002191Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002192 return FIELD_ADDR(this, kHeaderSize);
2193}
2194
2195
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002196char* SeqAsciiString::GetChars() {
2197 return reinterpret_cast<char*>(GetCharsAddress());
2198}
2199
2200
ager@chromium.org7c537e22008-10-16 08:43:32 +00002201Address SeqTwoByteString::GetCharsAddress() {
2202 return FIELD_ADDR(this, kHeaderSize);
2203}
2204
2205
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002206uc16* SeqTwoByteString::GetChars() {
2207 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2208}
2209
2210
ager@chromium.org7c537e22008-10-16 08:43:32 +00002211uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002212 ASSERT(index >= 0 && index < length());
2213 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2214}
2215
2216
ager@chromium.org7c537e22008-10-16 08:43:32 +00002217void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002218 ASSERT(index >= 0 && index < length());
2219 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2220}
2221
2222
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002223int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002224 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002225}
2226
2227
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002228int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002229 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002230}
2231
2232
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002233String* SlicedString::parent() {
2234 return String::cast(READ_FIELD(this, kParentOffset));
2235}
2236
2237
2238void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002239 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002240 WRITE_FIELD(this, kParentOffset, parent);
2241}
2242
2243
2244SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2245
2246
ager@chromium.org870a0b62008-11-04 11:43:05 +00002247String* ConsString::first() {
2248 return String::cast(READ_FIELD(this, kFirstOffset));
2249}
2250
2251
2252Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002253 return READ_FIELD(this, kFirstOffset);
2254}
2255
2256
ager@chromium.org870a0b62008-11-04 11:43:05 +00002257void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002258 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002259 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002260}
2261
2262
ager@chromium.org870a0b62008-11-04 11:43:05 +00002263String* ConsString::second() {
2264 return String::cast(READ_FIELD(this, kSecondOffset));
2265}
2266
2267
2268Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002269 return READ_FIELD(this, kSecondOffset);
2270}
2271
2272
ager@chromium.org870a0b62008-11-04 11:43:05 +00002273void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002274 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002275 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002276}
2277
2278
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002279const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002280 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2281}
2282
2283
2284void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002285 const ExternalAsciiString::Resource* resource) {
2286 *reinterpret_cast<const Resource**>(
2287 FIELD_ADDR(this, kResourceOffset)) = resource;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002288}
2289
2290
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002291const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002292 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2293}
2294
2295
2296void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002297 const ExternalTwoByteString::Resource* resource) {
2298 *reinterpret_cast<const Resource**>(
2299 FIELD_ADDR(this, kResourceOffset)) = resource;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002300}
2301
2302
ager@chromium.orgac091b72010-05-05 07:34:42 +00002303void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002304 set_finger_index(kEntriesIndex);
2305 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002306}
2307
2308
2309void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002310 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002311 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002312 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002313 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002314 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002315 MakeZeroSize();
2316}
2317
2318
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002319int JSFunctionResultCache::size() {
2320 return Smi::cast(get(kCacheSizeIndex))->value();
2321}
2322
2323
2324void JSFunctionResultCache::set_size(int size) {
2325 set(kCacheSizeIndex, Smi::FromInt(size));
2326}
2327
2328
2329int JSFunctionResultCache::finger_index() {
2330 return Smi::cast(get(kFingerIndex))->value();
2331}
2332
2333
2334void JSFunctionResultCache::set_finger_index(int finger_index) {
2335 set(kFingerIndex, Smi::FromInt(finger_index));
2336}
2337
2338
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002339byte ByteArray::get(int index) {
2340 ASSERT(index >= 0 && index < this->length());
2341 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2342}
2343
2344
2345void ByteArray::set(int index, byte value) {
2346 ASSERT(index >= 0 && index < this->length());
2347 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2348}
2349
2350
2351int ByteArray::get_int(int index) {
2352 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2353 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2354}
2355
2356
2357ByteArray* ByteArray::FromDataStartAddress(Address address) {
2358 ASSERT_TAG_ALIGNED(address);
2359 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2360}
2361
2362
2363Address ByteArray::GetDataStartAddress() {
2364 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2365}
2366
2367
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002368uint8_t* ExternalPixelArray::external_pixel_pointer() {
2369 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002370}
2371
2372
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002373uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002374 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002375 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002376 return ptr[index];
2377}
2378
2379
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002380MaybeObject* ExternalPixelArray::get(int index) {
2381 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2382}
2383
2384
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002385void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002386 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002387 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002388 ptr[index] = value;
2389}
2390
2391
ager@chromium.org3811b432009-10-28 14:53:37 +00002392void* ExternalArray::external_pointer() {
2393 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2394 return reinterpret_cast<void*>(ptr);
2395}
2396
2397
2398void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2399 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2400 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2401}
2402
2403
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002404int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002405 ASSERT((index >= 0) && (index < this->length()));
2406 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2407 return ptr[index];
2408}
2409
2410
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002411MaybeObject* ExternalByteArray::get(int index) {
2412 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2413}
2414
2415
ager@chromium.org3811b432009-10-28 14:53:37 +00002416void ExternalByteArray::set(int index, int8_t value) {
2417 ASSERT((index >= 0) && (index < this->length()));
2418 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2419 ptr[index] = value;
2420}
2421
2422
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002423uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002424 ASSERT((index >= 0) && (index < this->length()));
2425 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2426 return ptr[index];
2427}
2428
2429
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002430MaybeObject* ExternalUnsignedByteArray::get(int index) {
2431 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2432}
2433
2434
ager@chromium.org3811b432009-10-28 14:53:37 +00002435void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2436 ASSERT((index >= 0) && (index < this->length()));
2437 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2438 ptr[index] = value;
2439}
2440
2441
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002442int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002443 ASSERT((index >= 0) && (index < this->length()));
2444 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2445 return ptr[index];
2446}
2447
2448
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002449MaybeObject* ExternalShortArray::get(int index) {
2450 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2451}
2452
2453
ager@chromium.org3811b432009-10-28 14:53:37 +00002454void ExternalShortArray::set(int index, int16_t value) {
2455 ASSERT((index >= 0) && (index < this->length()));
2456 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2457 ptr[index] = value;
2458}
2459
2460
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002461uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002462 ASSERT((index >= 0) && (index < this->length()));
2463 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2464 return ptr[index];
2465}
2466
2467
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002468MaybeObject* ExternalUnsignedShortArray::get(int index) {
2469 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2470}
2471
2472
ager@chromium.org3811b432009-10-28 14:53:37 +00002473void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2474 ASSERT((index >= 0) && (index < this->length()));
2475 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2476 ptr[index] = value;
2477}
2478
2479
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002480int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002481 ASSERT((index >= 0) && (index < this->length()));
2482 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2483 return ptr[index];
2484}
2485
2486
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002487MaybeObject* ExternalIntArray::get(int index) {
2488 return GetHeap()->NumberFromInt32(get_scalar(index));
2489}
2490
2491
ager@chromium.org3811b432009-10-28 14:53:37 +00002492void ExternalIntArray::set(int index, int32_t value) {
2493 ASSERT((index >= 0) && (index < this->length()));
2494 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2495 ptr[index] = value;
2496}
2497
2498
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002499uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002500 ASSERT((index >= 0) && (index < this->length()));
2501 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2502 return ptr[index];
2503}
2504
2505
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002506MaybeObject* ExternalUnsignedIntArray::get(int index) {
2507 return GetHeap()->NumberFromUint32(get_scalar(index));
2508}
2509
2510
ager@chromium.org3811b432009-10-28 14:53:37 +00002511void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2512 ASSERT((index >= 0) && (index < this->length()));
2513 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2514 ptr[index] = value;
2515}
2516
2517
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002518float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002519 ASSERT((index >= 0) && (index < this->length()));
2520 float* ptr = static_cast<float*>(external_pointer());
2521 return ptr[index];
2522}
2523
2524
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002525MaybeObject* ExternalFloatArray::get(int index) {
2526 return GetHeap()->NumberFromDouble(get_scalar(index));
2527}
2528
2529
ager@chromium.org3811b432009-10-28 14:53:37 +00002530void ExternalFloatArray::set(int index, float value) {
2531 ASSERT((index >= 0) && (index < this->length()));
2532 float* ptr = static_cast<float*>(external_pointer());
2533 ptr[index] = value;
2534}
2535
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002536
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002537double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002538 ASSERT((index >= 0) && (index < this->length()));
2539 double* ptr = static_cast<double*>(external_pointer());
2540 return ptr[index];
2541}
2542
2543
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002544MaybeObject* ExternalDoubleArray::get(int index) {
2545 return GetHeap()->NumberFromDouble(get_scalar(index));
2546}
2547
2548
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002549void ExternalDoubleArray::set(int index, double value) {
2550 ASSERT((index >= 0) && (index < this->length()));
2551 double* ptr = static_cast<double*>(external_pointer());
2552 ptr[index] = value;
2553}
2554
2555
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002556int Map::visitor_id() {
2557 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2558}
2559
2560
2561void Map::set_visitor_id(int id) {
2562 ASSERT(0 <= id && id < 256);
2563 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2564}
2565
ager@chromium.org3811b432009-10-28 14:53:37 +00002566
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002567int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002568 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2569}
2570
2571
2572int Map::inobject_properties() {
2573 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002574}
2575
2576
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002577int Map::pre_allocated_property_fields() {
2578 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2579}
2580
2581
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002582int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002583 int instance_size = map->instance_size();
2584 if (instance_size != kVariableSizeSentinel) return instance_size;
2585 // We can ignore the "symbol" bit becase it is only set for symbols
2586 // and implies a string type.
2587 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002588 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002589 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002590 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002591 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002592 if (instance_type == ASCII_STRING_TYPE) {
2593 return SeqAsciiString::SizeFor(
2594 reinterpret_cast<SeqAsciiString*>(this)->length());
2595 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002596 if (instance_type == BYTE_ARRAY_TYPE) {
2597 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2598 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002599 if (instance_type == FREE_SPACE_TYPE) {
2600 return reinterpret_cast<FreeSpace*>(this)->size();
2601 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002602 if (instance_type == STRING_TYPE) {
2603 return SeqTwoByteString::SizeFor(
2604 reinterpret_cast<SeqTwoByteString*>(this)->length());
2605 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002606 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2607 return FixedDoubleArray::SizeFor(
2608 reinterpret_cast<FixedDoubleArray*>(this)->length());
2609 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002610 ASSERT(instance_type == CODE_TYPE);
2611 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002612}
2613
2614
2615void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002616 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002617 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002618 ASSERT(0 <= value && value < 256);
2619 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2620}
2621
2622
ager@chromium.org7c537e22008-10-16 08:43:32 +00002623void Map::set_inobject_properties(int value) {
2624 ASSERT(0 <= value && value < 256);
2625 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2626}
2627
2628
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002629void Map::set_pre_allocated_property_fields(int value) {
2630 ASSERT(0 <= value && value < 256);
2631 WRITE_BYTE_FIELD(this,
2632 kPreAllocatedPropertyFieldsOffset,
2633 static_cast<byte>(value));
2634}
2635
2636
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002637InstanceType Map::instance_type() {
2638 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2639}
2640
2641
2642void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002643 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2644}
2645
2646
2647int Map::unused_property_fields() {
2648 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2649}
2650
2651
2652void Map::set_unused_property_fields(int value) {
2653 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2654}
2655
2656
2657byte Map::bit_field() {
2658 return READ_BYTE_FIELD(this, kBitFieldOffset);
2659}
2660
2661
2662void Map::set_bit_field(byte value) {
2663 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2664}
2665
2666
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002667byte Map::bit_field2() {
2668 return READ_BYTE_FIELD(this, kBitField2Offset);
2669}
2670
2671
2672void Map::set_bit_field2(byte value) {
2673 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2674}
2675
2676
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002677void Map::set_non_instance_prototype(bool value) {
2678 if (value) {
2679 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2680 } else {
2681 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2682 }
2683}
2684
2685
2686bool Map::has_non_instance_prototype() {
2687 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2688}
2689
2690
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002691void Map::set_function_with_prototype(bool value) {
2692 if (value) {
2693 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2694 } else {
2695 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2696 }
2697}
2698
2699
2700bool Map::function_with_prototype() {
2701 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2702}
2703
2704
ager@chromium.org870a0b62008-11-04 11:43:05 +00002705void Map::set_is_access_check_needed(bool access_check_needed) {
2706 if (access_check_needed) {
2707 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2708 } else {
2709 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2710 }
2711}
2712
2713
2714bool Map::is_access_check_needed() {
2715 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2716}
2717
2718
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002719void Map::set_is_extensible(bool value) {
2720 if (value) {
2721 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2722 } else {
2723 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2724 }
2725}
2726
2727bool Map::is_extensible() {
2728 return ((1 << kIsExtensible) & bit_field2()) != 0;
2729}
2730
2731
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002732void Map::set_attached_to_shared_function_info(bool value) {
2733 if (value) {
2734 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2735 } else {
2736 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2737 }
2738}
2739
2740bool Map::attached_to_shared_function_info() {
2741 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2742}
2743
2744
2745void Map::set_is_shared(bool value) {
2746 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002747 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002748 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002749 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002750 }
2751}
2752
2753bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002754 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002755}
2756
2757
2758JSFunction* Map::unchecked_constructor() {
2759 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2760}
2761
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002762
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002763Code::Flags Code::flags() {
2764 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2765}
2766
2767
2768void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002769 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002770 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002771 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2772 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002773 ExtractArgumentsCountFromFlags(flags) >= 0);
2774 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2775}
2776
2777
2778Code::Kind Code::kind() {
2779 return ExtractKindFromFlags(flags());
2780}
2781
2782
kasper.lund7276f142008-07-30 08:49:36 +00002783InlineCacheState Code::ic_state() {
2784 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002785 // Only allow uninitialized or debugger states for non-IC code
2786 // objects. This is used in the debugger to determine whether or not
2787 // a call to code object has been replaced with a debug break call.
2788 ASSERT(is_inline_cache_stub() ||
2789 result == UNINITIALIZED ||
2790 result == DEBUG_BREAK ||
2791 result == DEBUG_PREPARE_STEP_IN);
2792 return result;
2793}
2794
2795
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002796Code::ExtraICState Code::extra_ic_state() {
2797 ASSERT(is_inline_cache_stub());
2798 return ExtractExtraICStateFromFlags(flags());
2799}
2800
2801
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002802PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002803 return ExtractTypeFromFlags(flags());
2804}
2805
2806
2807int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002808 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002809 return ExtractArgumentsCountFromFlags(flags());
2810}
2811
2812
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002813int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002814 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002815 kind() == UNARY_OP_IC ||
2816 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002817 kind() == COMPARE_IC ||
2818 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002819 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002820}
2821
2822
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002823void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002824 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002825 kind() == UNARY_OP_IC ||
2826 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002827 kind() == COMPARE_IC ||
2828 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002829 ASSERT(0 <= major && major < 256);
2830 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002831}
2832
2833
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002834bool Code::is_pregenerated() {
2835 return kind() == STUB && IsPregeneratedField::decode(flags());
2836}
2837
2838
2839void Code::set_is_pregenerated(bool value) {
2840 ASSERT(kind() == STUB);
2841 Flags f = flags();
2842 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
2843 set_flags(f);
2844}
2845
2846
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002847bool Code::optimizable() {
2848 ASSERT(kind() == FUNCTION);
2849 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2850}
2851
2852
2853void Code::set_optimizable(bool value) {
2854 ASSERT(kind() == FUNCTION);
2855 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2856}
2857
2858
2859bool Code::has_deoptimization_support() {
2860 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002861 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2862 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002863}
2864
2865
2866void Code::set_has_deoptimization_support(bool value) {
2867 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002868 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2869 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
2870 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
2871}
2872
2873
2874bool Code::has_debug_break_slots() {
2875 ASSERT(kind() == FUNCTION);
2876 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2877 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
2878}
2879
2880
2881void Code::set_has_debug_break_slots(bool value) {
2882 ASSERT(kind() == FUNCTION);
2883 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2884 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
2885 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002886}
2887
2888
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002889bool Code::is_compiled_optimizable() {
2890 ASSERT(kind() == FUNCTION);
2891 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2892 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
2893}
2894
2895
2896void Code::set_compiled_optimizable(bool value) {
2897 ASSERT(kind() == FUNCTION);
2898 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2899 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
2900 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
2901}
2902
2903
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002904int Code::allow_osr_at_loop_nesting_level() {
2905 ASSERT(kind() == FUNCTION);
2906 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2907}
2908
2909
2910void Code::set_allow_osr_at_loop_nesting_level(int level) {
2911 ASSERT(kind() == FUNCTION);
2912 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2913 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2914}
2915
2916
2917unsigned Code::stack_slots() {
2918 ASSERT(kind() == OPTIMIZED_FUNCTION);
2919 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2920}
2921
2922
2923void Code::set_stack_slots(unsigned slots) {
2924 ASSERT(kind() == OPTIMIZED_FUNCTION);
2925 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2926}
2927
2928
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002929unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002930 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002931 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002932}
2933
2934
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002935void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002936 ASSERT(kind() == OPTIMIZED_FUNCTION);
2937 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002938 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002939}
2940
2941
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002942unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002943 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002944 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002945}
2946
2947
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002948void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002949 ASSERT(kind() == FUNCTION);
2950 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002951 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002952}
2953
2954
2955CheckType Code::check_type() {
2956 ASSERT(is_call_stub() || is_keyed_call_stub());
2957 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2958 return static_cast<CheckType>(type);
2959}
2960
2961
2962void Code::set_check_type(CheckType value) {
2963 ASSERT(is_call_stub() || is_keyed_call_stub());
2964 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2965}
2966
2967
danno@chromium.org40cb8782011-05-25 07:58:50 +00002968byte Code::unary_op_type() {
2969 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002970 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
2971}
2972
2973
danno@chromium.org40cb8782011-05-25 07:58:50 +00002974void Code::set_unary_op_type(byte value) {
2975 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002976 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
2977}
2978
2979
danno@chromium.org40cb8782011-05-25 07:58:50 +00002980byte Code::binary_op_type() {
2981 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002982 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2983}
2984
2985
danno@chromium.org40cb8782011-05-25 07:58:50 +00002986void Code::set_binary_op_type(byte value) {
2987 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002988 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2989}
2990
2991
danno@chromium.org40cb8782011-05-25 07:58:50 +00002992byte Code::binary_op_result_type() {
2993 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002994 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2995}
2996
2997
danno@chromium.org40cb8782011-05-25 07:58:50 +00002998void Code::set_binary_op_result_type(byte value) {
2999 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003000 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3001}
3002
3003
3004byte Code::compare_state() {
3005 ASSERT(is_compare_ic_stub());
3006 return READ_BYTE_FIELD(this, kCompareStateOffset);
3007}
3008
3009
3010void Code::set_compare_state(byte value) {
3011 ASSERT(is_compare_ic_stub());
3012 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3013}
3014
3015
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003016byte Code::to_boolean_state() {
3017 ASSERT(is_to_boolean_ic_stub());
3018 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3019}
3020
3021
3022void Code::set_to_boolean_state(byte value) {
3023 ASSERT(is_to_boolean_ic_stub());
3024 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3025}
3026
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003027
3028bool Code::has_function_cache() {
3029 ASSERT(kind() == STUB);
3030 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3031}
3032
3033
3034void Code::set_has_function_cache(bool flag) {
3035 ASSERT(kind() == STUB);
3036 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3037}
3038
3039
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003040bool Code::is_inline_cache_stub() {
3041 Kind kind = this->kind();
3042 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3043}
3044
3045
3046Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003047 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003048 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003049 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003050 int argc,
3051 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003052 // Extra IC state is only allowed for call IC stubs or for store IC
3053 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003054 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003055 kind == CALL_IC ||
3056 kind == STORE_IC ||
3057 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003058 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003059 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003060 | ICStateField::encode(ic_state)
3061 | TypeField::encode(type)
3062 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003063 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003064 | CacheHolderField::encode(holder);
3065 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003066}
3067
3068
3069Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3070 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003071 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003072 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003073 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003074 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003075}
3076
3077
3078Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003079 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003080}
3081
3082
kasper.lund7276f142008-07-30 08:49:36 +00003083InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003084 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003085}
3086
3087
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003088Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003089 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003090}
3091
3092
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003093PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003094 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003095}
3096
3097
3098int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003099 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003100}
3101
3102
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003103InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003104 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003105}
3106
3107
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003108Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003109 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003110 return static_cast<Flags>(bits);
3111}
3112
3113
ager@chromium.org8bb60582008-12-11 12:02:20 +00003114Code* Code::GetCodeFromTargetAddress(Address address) {
3115 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3116 // GetCodeFromTargetAddress might be called when marking objects during mark
3117 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3118 // Code::cast. Code::cast does not work when the object's map is
3119 // marked.
3120 Code* result = reinterpret_cast<Code*>(code);
3121 return result;
3122}
3123
3124
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003125Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3126 return HeapObject::
3127 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3128}
3129
3130
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003131Object* Map::prototype() {
3132 return READ_FIELD(this, kPrototypeOffset);
3133}
3134
3135
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003136void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003137 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003138 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003139 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003140}
3141
3142
danno@chromium.org40cb8782011-05-25 07:58:50 +00003143DescriptorArray* Map::instance_descriptors() {
3144 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3145 if (object->IsSmi()) {
3146 return HEAP->empty_descriptor_array();
3147 } else {
3148 return DescriptorArray::cast(object);
3149 }
3150}
3151
3152
3153void Map::init_instance_descriptors() {
3154 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3155}
3156
3157
3158void Map::clear_instance_descriptors() {
3159 Object* object = READ_FIELD(this,
3160 kInstanceDescriptorsOrBitField3Offset);
3161 if (!object->IsSmi()) {
3162 WRITE_FIELD(
3163 this,
3164 kInstanceDescriptorsOrBitField3Offset,
3165 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3166 }
3167}
3168
3169
3170void Map::set_instance_descriptors(DescriptorArray* value,
3171 WriteBarrierMode mode) {
3172 Object* object = READ_FIELD(this,
3173 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003174 Heap* heap = GetHeap();
3175 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003176 clear_instance_descriptors();
3177 return;
3178 } else {
3179 if (object->IsSmi()) {
3180 value->set_bit_field3_storage(Smi::cast(object)->value());
3181 } else {
3182 value->set_bit_field3_storage(
3183 DescriptorArray::cast(object)->bit_field3_storage());
3184 }
3185 }
3186 ASSERT(!is_shared());
3187 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003188 CONDITIONAL_WRITE_BARRIER(
3189 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003190}
3191
3192
3193int Map::bit_field3() {
3194 Object* object = READ_FIELD(this,
3195 kInstanceDescriptorsOrBitField3Offset);
3196 if (object->IsSmi()) {
3197 return Smi::cast(object)->value();
3198 } else {
3199 return DescriptorArray::cast(object)->bit_field3_storage();
3200 }
3201}
3202
3203
3204void Map::set_bit_field3(int value) {
3205 ASSERT(Smi::IsValid(value));
3206 Object* object = READ_FIELD(this,
3207 kInstanceDescriptorsOrBitField3Offset);
3208 if (object->IsSmi()) {
3209 WRITE_FIELD(this,
3210 kInstanceDescriptorsOrBitField3Offset,
3211 Smi::FromInt(value));
3212 } else {
3213 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3214 }
3215}
3216
3217
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003218FixedArray* Map::unchecked_prototype_transitions() {
3219 return reinterpret_cast<FixedArray*>(
3220 READ_FIELD(this, kPrototypeTransitionsOffset));
3221}
3222
3223
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003224ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003225ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003226ACCESSORS(Map, constructor, Object, kConstructorOffset)
3227
3228ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003229ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003230ACCESSORS(JSFunction,
3231 next_function_link,
3232 Object,
3233 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003234
3235ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3236ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003237ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003238
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003239ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003240
3241ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3242ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3243ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3244ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3245ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3246
3247ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3248ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3249ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3250
3251ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3252ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3253ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3254ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3255ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3256ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3257
3258ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3259ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3260
3261ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3262ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3263
3264ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3265ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003266ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3267 kPropertyAccessorsOffset)
3268ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3269 kPrototypeTemplateOffset)
3270ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3271ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3272 kNamedPropertyHandlerOffset)
3273ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3274 kIndexedPropertyHandlerOffset)
3275ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3276 kInstanceTemplateOffset)
3277ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3278ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003279ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3280 kInstanceCallHandlerOffset)
3281ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3282 kAccessCheckInfoOffset)
3283ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3284
3285ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003286ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3287 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003288
3289ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3290ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3291
3292ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3293
3294ACCESSORS(Script, source, Object, kSourceOffset)
3295ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003296ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003297ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3298ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003299ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003300ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003301ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003302ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003303ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003304ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003305ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003306ACCESSORS(Script, eval_from_instructions_offset, Smi,
3307 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003308
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003309#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003310ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3311ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3312ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3313ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3314
3315ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3316ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3317ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3318ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003319#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003320
3321ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003322ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3323ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003324ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3325 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003326ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003327ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3328ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003329ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003330ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3331 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003332
3333BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3334 kHiddenPrototypeBit)
3335BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3336BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3337 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003338BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3339 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003340BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3341 kIsExpressionBit)
3342BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3343 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003344BOOL_GETTER(SharedFunctionInfo,
3345 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003346 has_only_simple_this_property_assignments,
3347 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003348BOOL_ACCESSORS(SharedFunctionInfo,
3349 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003350 allows_lazy_compilation,
3351 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003352BOOL_ACCESSORS(SharedFunctionInfo,
3353 compiler_hints,
3354 uses_arguments,
3355 kUsesArguments)
3356BOOL_ACCESSORS(SharedFunctionInfo,
3357 compiler_hints,
3358 has_duplicate_parameters,
3359 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003360
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003361
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003362#if V8_HOST_ARCH_32_BIT
3363SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3364SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003365 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003366SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003367 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003368SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3369SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003370 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003371SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3372SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003373 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003374SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003375 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003376SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003377 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003378SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003379#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003380
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003381#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003382 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003383 int holder::name() { \
3384 int value = READ_INT_FIELD(this, offset); \
3385 ASSERT(kHeapObjectTag == 1); \
3386 ASSERT((value & kHeapObjectTag) == 0); \
3387 return value >> 1; \
3388 } \
3389 void holder::set_##name(int value) { \
3390 ASSERT(kHeapObjectTag == 1); \
3391 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3392 (value & 0xC0000000) == 0x000000000); \
3393 WRITE_INT_FIELD(this, \
3394 offset, \
3395 (value << 1) & ~kHeapObjectTag); \
3396 }
3397
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003398#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3399 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003400 INT_ACCESSORS(holder, name, offset)
3401
3402
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003403PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003404PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3405 formal_parameter_count,
3406 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003407
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003408PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3409 expected_nof_properties,
3410 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003411PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3412
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003413PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3414PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3415 start_position_and_type,
3416 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003417
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003418PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3419 function_token_position,
3420 kFunctionTokenPositionOffset)
3421PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3422 compiler_hints,
3423 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003424
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003425PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3426 this_property_assignments_count,
3427 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003428PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003429#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003430
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003431
3432int SharedFunctionInfo::construction_count() {
3433 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3434}
3435
3436
3437void SharedFunctionInfo::set_construction_count(int value) {
3438 ASSERT(0 <= value && value < 256);
3439 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3440}
3441
3442
whesse@chromium.org7b260152011-06-20 15:33:18 +00003443BOOL_ACCESSORS(SharedFunctionInfo,
3444 compiler_hints,
3445 live_objects_may_exist,
3446 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003447
3448
3449bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003450 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003451}
3452
3453
whesse@chromium.org7b260152011-06-20 15:33:18 +00003454BOOL_GETTER(SharedFunctionInfo,
3455 compiler_hints,
3456 optimization_disabled,
3457 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003458
3459
3460void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3461 set_compiler_hints(BooleanBit::set(compiler_hints(),
3462 kOptimizationDisabled,
3463 disable));
3464 // If disabling optimizations we reflect that in the code object so
3465 // it will not be counted as optimizable code.
3466 if ((code()->kind() == Code::FUNCTION) && disable) {
3467 code()->set_optimizable(false);
3468 }
3469}
3470
3471
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003472StrictModeFlag SharedFunctionInfo::strict_mode_flag() {
3473 return BooleanBit::get(compiler_hints(), kStrictModeFunction)
3474 ? kStrictMode : kNonStrictMode;
3475}
3476
3477
3478void SharedFunctionInfo::set_strict_mode_flag(StrictModeFlag strict_mode_flag) {
3479 ASSERT(strict_mode_flag == kStrictMode ||
3480 strict_mode_flag == kNonStrictMode);
3481 bool value = strict_mode_flag == kStrictMode;
3482 set_compiler_hints(
3483 BooleanBit::set(compiler_hints(), kStrictModeFunction, value));
3484}
3485
3486
3487BOOL_GETTER(SharedFunctionInfo, compiler_hints, strict_mode,
3488 kStrictModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003489BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3490BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3491 name_should_print_as_anonymous,
3492 kNameShouldPrintAsAnonymous)
3493BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3494BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003495
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003496ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3497ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3498
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003499ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3500
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003501bool Script::HasValidSource() {
3502 Object* src = this->source();
3503 if (!src->IsString()) return true;
3504 String* src_str = String::cast(src);
3505 if (!StringShape(src_str).IsExternal()) return true;
3506 if (src_str->IsAsciiRepresentation()) {
3507 return ExternalAsciiString::cast(src)->resource() != NULL;
3508 } else if (src_str->IsTwoByteRepresentation()) {
3509 return ExternalTwoByteString::cast(src)->resource() != NULL;
3510 }
3511 return true;
3512}
3513
3514
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003515void SharedFunctionInfo::DontAdaptArguments() {
3516 ASSERT(code()->kind() == Code::BUILTIN);
3517 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3518}
3519
3520
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003521int SharedFunctionInfo::start_position() {
3522 return start_position_and_type() >> kStartPositionShift;
3523}
3524
3525
3526void SharedFunctionInfo::set_start_position(int start_position) {
3527 set_start_position_and_type((start_position << kStartPositionShift)
3528 | (start_position_and_type() & ~kStartPositionMask));
3529}
3530
3531
3532Code* SharedFunctionInfo::code() {
3533 return Code::cast(READ_FIELD(this, kCodeOffset));
3534}
3535
3536
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003537Code* SharedFunctionInfo::unchecked_code() {
3538 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3539}
3540
3541
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003542void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003543 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003544 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003545}
3546
3547
ager@chromium.orgb5737492010-07-15 09:29:43 +00003548SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3549 return reinterpret_cast<SerializedScopeInfo*>(
3550 READ_FIELD(this, kScopeInfoOffset));
3551}
3552
3553
3554void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3555 WriteBarrierMode mode) {
3556 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003557 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3558 this,
3559 kScopeInfoOffset,
3560 reinterpret_cast<Object*>(value),
3561 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003562}
3563
3564
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003565Smi* SharedFunctionInfo::deopt_counter() {
3566 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3567}
3568
3569
3570void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3571 WRITE_FIELD(this, kDeoptCounterOffset, value);
3572}
3573
3574
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003575bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003576 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003577 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003578}
3579
3580
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003581bool SharedFunctionInfo::IsApiFunction() {
3582 return function_data()->IsFunctionTemplateInfo();
3583}
3584
3585
3586FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3587 ASSERT(IsApiFunction());
3588 return FunctionTemplateInfo::cast(function_data());
3589}
3590
3591
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003592bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003593 return function_data()->IsSmi();
3594}
3595
3596
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003597BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3598 ASSERT(HasBuiltinFunctionId());
3599 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003600}
3601
3602
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003603int SharedFunctionInfo::code_age() {
3604 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3605}
3606
3607
3608void SharedFunctionInfo::set_code_age(int code_age) {
3609 set_compiler_hints(compiler_hints() |
3610 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3611}
3612
3613
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003614bool SharedFunctionInfo::has_deoptimization_support() {
3615 Code* code = this->code();
3616 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3617}
3618
3619
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003620bool JSFunction::IsBuiltin() {
3621 return context()->global()->IsJSBuiltinsObject();
3622}
3623
3624
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003625bool JSFunction::NeedsArgumentsAdaption() {
3626 return shared()->formal_parameter_count() !=
3627 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3628}
3629
3630
3631bool JSFunction::IsOptimized() {
3632 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3633}
3634
3635
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003636bool JSFunction::IsOptimizable() {
3637 return code()->kind() == Code::FUNCTION && code()->optimizable();
3638}
3639
3640
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003641bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003642 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003643}
3644
3645
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003646Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003647 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003648}
3649
3650
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003651Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003652 return reinterpret_cast<Code*>(
3653 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003654}
3655
3656
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003657void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003658 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003659 Address entry = value->entry();
3660 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003661 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3662 this,
3663 HeapObject::RawField(this, kCodeEntryOffset),
3664 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003665}
3666
3667
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003668void JSFunction::ReplaceCode(Code* code) {
3669 bool was_optimized = IsOptimized();
3670 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3671
3672 set_code(code);
3673
3674 // Add/remove the function from the list of optimized functions for this
3675 // context based on the state change.
3676 if (!was_optimized && is_optimized) {
3677 context()->global_context()->AddOptimizedFunction(this);
3678 }
3679 if (was_optimized && !is_optimized) {
3680 context()->global_context()->RemoveOptimizedFunction(this);
3681 }
3682}
3683
3684
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003685Context* JSFunction::context() {
3686 return Context::cast(READ_FIELD(this, kContextOffset));
3687}
3688
3689
3690Object* JSFunction::unchecked_context() {
3691 return READ_FIELD(this, kContextOffset);
3692}
3693
3694
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003695SharedFunctionInfo* JSFunction::unchecked_shared() {
3696 return reinterpret_cast<SharedFunctionInfo*>(
3697 READ_FIELD(this, kSharedFunctionInfoOffset));
3698}
3699
3700
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003701void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003702 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003703 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003704 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003705}
3706
3707ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3708 kPrototypeOrInitialMapOffset)
3709
3710
3711Map* JSFunction::initial_map() {
3712 return Map::cast(prototype_or_initial_map());
3713}
3714
3715
3716void JSFunction::set_initial_map(Map* value) {
3717 set_prototype_or_initial_map(value);
3718}
3719
3720
3721bool JSFunction::has_initial_map() {
3722 return prototype_or_initial_map()->IsMap();
3723}
3724
3725
3726bool JSFunction::has_instance_prototype() {
3727 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3728}
3729
3730
3731bool JSFunction::has_prototype() {
3732 return map()->has_non_instance_prototype() || has_instance_prototype();
3733}
3734
3735
3736Object* JSFunction::instance_prototype() {
3737 ASSERT(has_instance_prototype());
3738 if (has_initial_map()) return initial_map()->prototype();
3739 // When there is no initial map and the prototype is a JSObject, the
3740 // initial map field is used for the prototype field.
3741 return prototype_or_initial_map();
3742}
3743
3744
3745Object* JSFunction::prototype() {
3746 ASSERT(has_prototype());
3747 // If the function's prototype property has been set to a non-JSObject
3748 // value, that value is stored in the constructor field of the map.
3749 if (map()->has_non_instance_prototype()) return map()->constructor();
3750 return instance_prototype();
3751}
3752
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003753bool JSFunction::should_have_prototype() {
3754 return map()->function_with_prototype();
3755}
3756
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003757
3758bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003759 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003760}
3761
3762
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003763FixedArray* JSFunction::literals() {
3764 ASSERT(!shared()->bound());
3765 return literals_or_bindings();
3766}
3767
3768
3769void JSFunction::set_literals(FixedArray* literals) {
3770 ASSERT(!shared()->bound());
3771 set_literals_or_bindings(literals);
3772}
3773
3774
3775FixedArray* JSFunction::function_bindings() {
3776 ASSERT(shared()->bound());
3777 return literals_or_bindings();
3778}
3779
3780
3781void JSFunction::set_function_bindings(FixedArray* bindings) {
3782 ASSERT(shared()->bound());
3783 // Bound function literal may be initialized to the empty fixed array
3784 // before the bindings are set.
3785 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
3786 bindings->map() == GetHeap()->fixed_cow_array_map());
3787 set_literals_or_bindings(bindings);
3788}
3789
3790
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003791int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003792 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003793 return literals()->length();
3794}
3795
3796
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003797Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003798 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003799 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003800}
3801
3802
3803void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3804 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003805 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003806 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003807 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003808}
3809
3810
3811Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003812 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003813 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3814}
3815
3816
3817void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3818 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003819 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003820 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003821 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003822}
3823
3824
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003825ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003826ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003827ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
3828ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
3829
3830
3831void JSProxy::InitializeBody(int object_size, Object* value) {
3832 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
3833 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
3834 WRITE_FIELD(this, offset, value);
3835 }
3836}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003837
3838
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003839ACCESSORS(JSSet, table, Object, kTableOffset)
3840ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003841ACCESSORS(JSWeakMap, table, Object, kTableOffset)
3842ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003843
3844
3845ObjectHashTable* JSWeakMap::unchecked_table() {
3846 return reinterpret_cast<ObjectHashTable*>(READ_FIELD(this, kTableOffset));
3847}
3848
3849
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003850Address Foreign::address() {
3851 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003852}
3853
3854
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003855void Foreign::set_address(Address value) {
3856 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003857}
3858
3859
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003860ACCESSORS(JSValue, value, Object, kValueOffset)
3861
3862
3863JSValue* JSValue::cast(Object* obj) {
3864 ASSERT(obj->IsJSValue());
3865 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3866 return reinterpret_cast<JSValue*>(obj);
3867}
3868
3869
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003870ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3871ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3872ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3873ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3874ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3875SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3876SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3877
3878
3879JSMessageObject* JSMessageObject::cast(Object* obj) {
3880 ASSERT(obj->IsJSMessageObject());
3881 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3882 return reinterpret_cast<JSMessageObject*>(obj);
3883}
3884
3885
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003886INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003887ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003888ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003889ACCESSORS(Code, next_code_flushing_candidate,
3890 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003891
3892
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003893byte* Code::instruction_start() {
3894 return FIELD_ADDR(this, kHeaderSize);
3895}
3896
3897
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003898byte* Code::instruction_end() {
3899 return instruction_start() + instruction_size();
3900}
3901
3902
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003903int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003904 return RoundUp(instruction_size(), kObjectAlignment);
3905}
3906
3907
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003908FixedArray* Code::unchecked_deoptimization_data() {
3909 return reinterpret_cast<FixedArray*>(
3910 READ_FIELD(this, kDeoptimizationDataOffset));
3911}
3912
3913
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003914ByteArray* Code::unchecked_relocation_info() {
3915 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003916}
3917
3918
3919byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003920 return unchecked_relocation_info()->GetDataStartAddress();
3921}
3922
3923
3924int Code::relocation_size() {
3925 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003926}
3927
3928
3929byte* Code::entry() {
3930 return instruction_start();
3931}
3932
3933
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003934bool Code::contains(byte* inner_pointer) {
3935 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003936}
3937
3938
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003939ACCESSORS(JSArray, length, Object, kLengthOffset)
3940
3941
ager@chromium.org236ad962008-09-25 09:45:57 +00003942ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003943
3944
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003945JSRegExp::Type JSRegExp::TypeTag() {
3946 Object* data = this->data();
3947 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3948 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3949 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003950}
3951
3952
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003953JSRegExp::Type JSRegExp::TypeTagUnchecked() {
3954 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
3955 return static_cast<JSRegExp::Type>(smi->value());
3956}
3957
3958
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003959int JSRegExp::CaptureCount() {
3960 switch (TypeTag()) {
3961 case ATOM:
3962 return 0;
3963 case IRREGEXP:
3964 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3965 default:
3966 UNREACHABLE();
3967 return -1;
3968 }
3969}
3970
3971
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003972JSRegExp::Flags JSRegExp::GetFlags() {
3973 ASSERT(this->data()->IsFixedArray());
3974 Object* data = this->data();
3975 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3976 return Flags(smi->value());
3977}
3978
3979
3980String* JSRegExp::Pattern() {
3981 ASSERT(this->data()->IsFixedArray());
3982 Object* data = this->data();
3983 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3984 return pattern;
3985}
3986
3987
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003988Object* JSRegExp::DataAt(int index) {
3989 ASSERT(TypeTag() != NOT_COMPILED);
3990 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003991}
3992
3993
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003994Object* JSRegExp::DataAtUnchecked(int index) {
3995 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
3996 int offset = FixedArray::kHeaderSize + index * kPointerSize;
3997 return READ_FIELD(fa, offset);
3998}
3999
4000
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004001void JSRegExp::SetDataAt(int index, Object* value) {
4002 ASSERT(TypeTag() != NOT_COMPILED);
4003 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4004 FixedArray::cast(data())->set(index, value);
4005}
4006
4007
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004008void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4009 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4010 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4011 if (value->IsSmi()) {
4012 fa->set_unchecked(index, Smi::cast(value));
4013 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004014 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004015 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4016 }
4017}
4018
4019
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004020ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004021 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004022#if DEBUG
4023 FixedArrayBase* fixed_array =
4024 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4025 Map* map = fixed_array->map();
4026 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004027 (map == GetHeap()->fixed_array_map() ||
4028 map == GetHeap()->fixed_cow_array_map())) ||
4029 (kind == FAST_DOUBLE_ELEMENTS &&
4030 fixed_array->IsFixedDoubleArray()) ||
4031 (kind == DICTIONARY_ELEMENTS &&
4032 fixed_array->IsFixedArray() &&
4033 fixed_array->IsDictionary()) ||
4034 (kind > DICTIONARY_ELEMENTS));
4035 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4036 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004037#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004038 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004039}
4040
4041
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004042ElementsAccessor* JSObject::GetElementsAccessor() {
4043 return ElementsAccessor::ForKind(GetElementsKind());
4044}
4045
4046
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004047bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004048 return GetElementsKind() == FAST_ELEMENTS;
4049}
4050
4051
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004052bool JSObject::HasFastSmiOnlyElements() {
4053 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4054}
4055
4056
4057bool JSObject::HasFastTypeElements() {
4058 ElementsKind elements_kind = GetElementsKind();
4059 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4060 elements_kind == FAST_ELEMENTS;
4061}
4062
4063
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004064bool JSObject::HasFastDoubleElements() {
4065 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4066}
4067
4068
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004069bool JSObject::HasDictionaryElements() {
4070 return GetElementsKind() == DICTIONARY_ELEMENTS;
4071}
4072
4073
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004074bool JSObject::HasNonStrictArgumentsElements() {
4075 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4076}
4077
4078
ager@chromium.org3811b432009-10-28 14:53:37 +00004079bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004080 HeapObject* array = elements();
4081 ASSERT(array != NULL);
4082 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004083}
4084
4085
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004086#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4087bool JSObject::HasExternal##name##Elements() { \
4088 HeapObject* array = elements(); \
4089 ASSERT(array != NULL); \
4090 if (!array->IsHeapObject()) \
4091 return false; \
4092 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004093}
4094
4095
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004096EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4097EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4098EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4099EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4100 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4101EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4102EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4103 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4104EXTERNAL_ELEMENTS_CHECK(Float,
4105 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004106EXTERNAL_ELEMENTS_CHECK(Double,
4107 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004108EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004109
4110
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004111bool JSObject::HasNamedInterceptor() {
4112 return map()->has_named_interceptor();
4113}
4114
4115
4116bool JSObject::HasIndexedInterceptor() {
4117 return map()->has_indexed_interceptor();
4118}
4119
4120
ager@chromium.org5c838252010-02-19 08:53:10 +00004121bool JSObject::AllowsSetElementsLength() {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004122 bool result = elements()->IsFixedArray() ||
4123 elements()->IsFixedDoubleArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004124 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00004125 return result;
4126}
4127
4128
lrn@chromium.org303ada72010-10-27 09:33:13 +00004129MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004130 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004131 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004132 Isolate* isolate = GetIsolate();
4133 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004134 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004135 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4136 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004137 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4138 return maybe_writable_elems;
4139 }
4140 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004141 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004142 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004143 return writable_elems;
4144}
4145
4146
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004147StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004148 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004149 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004150}
4151
4152
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004153NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004154 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004155 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004156}
4157
4158
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004159bool String::IsHashFieldComputed(uint32_t field) {
4160 return (field & kHashNotComputedMask) == 0;
4161}
4162
4163
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004164bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004165 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004166}
4167
4168
4169uint32_t String::Hash() {
4170 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004171 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004172 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004173 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004174 return ComputeAndSetHash();
4175}
4176
4177
ager@chromium.org7c537e22008-10-16 08:43:32 +00004178StringHasher::StringHasher(int length)
4179 : length_(length),
4180 raw_running_hash_(0),
4181 array_index_(0),
4182 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4183 is_first_char_(true),
4184 is_valid_(true) { }
4185
4186
4187bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004188 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004189}
4190
4191
4192void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004193 // Use the Jenkins one-at-a-time hash function to update the hash
4194 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004195 raw_running_hash_ += c;
4196 raw_running_hash_ += (raw_running_hash_ << 10);
4197 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004198 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004199 if (is_array_index_) {
4200 if (c < '0' || c > '9') {
4201 is_array_index_ = false;
4202 } else {
4203 int d = c - '0';
4204 if (is_first_char_) {
4205 is_first_char_ = false;
4206 if (c == '0' && length_ > 1) {
4207 is_array_index_ = false;
4208 return;
4209 }
4210 }
4211 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4212 is_array_index_ = false;
4213 } else {
4214 array_index_ = array_index_ * 10 + d;
4215 }
4216 }
4217 }
4218}
4219
4220
4221void StringHasher::AddCharacterNoIndex(uc32 c) {
4222 ASSERT(!is_array_index());
4223 raw_running_hash_ += c;
4224 raw_running_hash_ += (raw_running_hash_ << 10);
4225 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4226}
4227
4228
4229uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004230 // Get the calculated raw hash value and do some more bit ops to distribute
4231 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004232 uint32_t result = raw_running_hash_;
4233 result += (result << 3);
4234 result ^= (result >> 11);
4235 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004236 if (result == 0) {
4237 result = 27;
4238 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004239 return result;
4240}
4241
4242
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004243template <typename schar>
4244uint32_t HashSequentialString(const schar* chars, int length) {
4245 StringHasher hasher(length);
4246 if (!hasher.has_trivial_hash()) {
4247 int i;
4248 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4249 hasher.AddCharacter(chars[i]);
4250 }
4251 for (; i < length; i++) {
4252 hasher.AddCharacterNoIndex(chars[i]);
4253 }
4254 }
4255 return hasher.GetHashField();
4256}
4257
4258
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004259bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004260 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004261 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4262 return false;
4263 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004264 return SlowAsArrayIndex(index);
4265}
4266
4267
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004268Object* JSReceiver::GetPrototype() {
4269 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004270}
4271
4272
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004273bool JSReceiver::HasProperty(String* name) {
4274 if (IsJSProxy()) {
4275 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4276 }
4277 return GetPropertyAttribute(name) != ABSENT;
4278}
4279
4280
4281bool JSReceiver::HasLocalProperty(String* name) {
4282 if (IsJSProxy()) {
4283 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4284 }
4285 return GetLocalPropertyAttribute(name) != ABSENT;
4286}
4287
4288
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004289PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004290 return GetPropertyAttributeWithReceiver(this, key);
4291}
4292
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004293// TODO(504): this may be useful in other places too where JSGlobalProxy
4294// is used.
4295Object* JSObject::BypassGlobalProxy() {
4296 if (IsJSGlobalProxy()) {
4297 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004298 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004299 ASSERT(proto->IsJSGlobalObject());
4300 return proto;
4301 }
4302 return this;
4303}
4304
4305
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004306MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4307 return IsJSProxy()
4308 ? JSProxy::cast(this)->GetIdentityHash(flag)
4309 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004310}
4311
4312
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004313bool JSReceiver::HasElement(uint32_t index) {
4314 if (IsJSProxy()) {
4315 return JSProxy::cast(this)->HasElementWithHandler(index);
4316 }
4317 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004318}
4319
4320
4321bool AccessorInfo::all_can_read() {
4322 return BooleanBit::get(flag(), kAllCanReadBit);
4323}
4324
4325
4326void AccessorInfo::set_all_can_read(bool value) {
4327 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4328}
4329
4330
4331bool AccessorInfo::all_can_write() {
4332 return BooleanBit::get(flag(), kAllCanWriteBit);
4333}
4334
4335
4336void AccessorInfo::set_all_can_write(bool value) {
4337 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4338}
4339
4340
ager@chromium.org870a0b62008-11-04 11:43:05 +00004341bool AccessorInfo::prohibits_overwriting() {
4342 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4343}
4344
4345
4346void AccessorInfo::set_prohibits_overwriting(bool value) {
4347 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4348}
4349
4350
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004351PropertyAttributes AccessorInfo::property_attributes() {
4352 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4353}
4354
4355
4356void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004357 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004358}
4359
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004360
4361template<typename Shape, typename Key>
4362void Dictionary<Shape, Key>::SetEntry(int entry,
4363 Object* key,
4364 Object* value) {
4365 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4366}
4367
4368
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004369template<typename Shape, typename Key>
4370void Dictionary<Shape, Key>::SetEntry(int entry,
4371 Object* key,
4372 Object* value,
4373 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004374 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004375 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004376 AssertNoAllocation no_gc;
4377 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004378 FixedArray::set(index, key, mode);
4379 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004380 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004381}
4382
4383
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004384bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4385 ASSERT(other->IsNumber());
4386 return key == static_cast<uint32_t>(other->Number());
4387}
4388
4389
4390uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4391 return ComputeIntegerHash(key);
4392}
4393
4394
4395uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4396 ASSERT(other->IsNumber());
4397 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4398}
4399
4400
4401MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4402 return Isolate::Current()->heap()->NumberFromUint32(key);
4403}
4404
4405
4406bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4407 // We know that all entries in a hash table had their hash keys created.
4408 // Use that knowledge to have fast failure.
4409 if (key->Hash() != String::cast(other)->Hash()) return false;
4410 return key->Equals(String::cast(other));
4411}
4412
4413
4414uint32_t StringDictionaryShape::Hash(String* key) {
4415 return key->Hash();
4416}
4417
4418
4419uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4420 return String::cast(other)->Hash();
4421}
4422
4423
4424MaybeObject* StringDictionaryShape::AsObject(String* key) {
4425 return key;
4426}
4427
4428
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004429template <int entrysize>
4430bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4431 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004432}
4433
4434
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004435template <int entrysize>
4436uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
4437 ASSERT(!key->IsUndefined() && !key->IsNull());
4438 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4439 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004440}
4441
4442
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004443template <int entrysize>
4444uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4445 Object* other) {
4446 ASSERT(!other->IsUndefined() && !other->IsNull());
4447 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4448 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004449}
4450
4451
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004452template <int entrysize>
4453MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004454 return key;
4455}
4456
4457
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004458void ObjectHashTable::RemoveEntry(int entry) {
4459 RemoveEntry(entry, GetHeap());
4460}
4461
4462
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004463void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004464 // No write barrier is needed since empty_fixed_array is not in new space.
4465 // Please note this function is used during marking:
4466 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004467 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4468 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004469}
4470
4471
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004472void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004473 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004474 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004475 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4476 if (elts->length() < required_size) {
4477 // Doubling in size would be overkill, but leave some slack to avoid
4478 // constantly growing.
4479 Expand(required_size + (required_size >> 3));
4480 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004481 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004482 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4483 // Expand will allocate a new backing store in new space even if the size
4484 // we asked for isn't larger than what we had before.
4485 Expand(required_size);
4486 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004487}
4488
4489
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004490void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004491 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004492 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4493}
4494
4495
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004496MaybeObject* JSArray::SetContent(FixedArray* storage) {
4497 MaybeObject* maybe_object = EnsureCanContainElements(storage);
4498 if (maybe_object->IsFailure()) return maybe_object;
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004499 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004500 set_elements(storage);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004501 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004502}
4503
4504
lrn@chromium.org303ada72010-10-27 09:33:13 +00004505MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004506 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004507 return GetHeap()->CopyFixedArray(this);
4508}
4509
4510
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004511MaybeObject* FixedDoubleArray::Copy() {
4512 if (length() == 0) return this;
4513 return GetHeap()->CopyFixedDoubleArray(this);
4514}
4515
4516
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004517Relocatable::Relocatable(Isolate* isolate) {
4518 ASSERT(isolate == Isolate::Current());
4519 isolate_ = isolate;
4520 prev_ = isolate->relocatable_top();
4521 isolate->set_relocatable_top(this);
4522}
4523
4524
4525Relocatable::~Relocatable() {
4526 ASSERT(isolate_ == Isolate::Current());
4527 ASSERT_EQ(isolate_->relocatable_top(), this);
4528 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004529}
4530
4531
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004532int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4533 return map->instance_size();
4534}
4535
4536
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004537void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004538 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004539 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004540}
4541
4542
4543template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004544void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004545 StaticVisitor::VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004546 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004547}
4548
4549
4550void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4551 typedef v8::String::ExternalAsciiStringResource Resource;
4552 v->VisitExternalAsciiString(
4553 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4554}
4555
4556
4557template<typename StaticVisitor>
4558void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4559 typedef v8::String::ExternalAsciiStringResource Resource;
4560 StaticVisitor::VisitExternalAsciiString(
4561 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4562}
4563
4564
4565void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4566 typedef v8::String::ExternalStringResource Resource;
4567 v->VisitExternalTwoByteString(
4568 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4569}
4570
4571
4572template<typename StaticVisitor>
4573void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4574 typedef v8::String::ExternalStringResource Resource;
4575 StaticVisitor::VisitExternalTwoByteString(
4576 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4577}
4578
4579#define SLOT_ADDR(obj, offset) \
4580 reinterpret_cast<Object**>((obj)->address() + offset)
4581
4582template<int start_offset, int end_offset, int size>
4583void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4584 HeapObject* obj,
4585 ObjectVisitor* v) {
4586 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4587}
4588
4589
4590template<int start_offset>
4591void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4592 int object_size,
4593 ObjectVisitor* v) {
4594 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4595}
4596
4597#undef SLOT_ADDR
4598
4599
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004600#undef CAST_ACCESSOR
4601#undef INT_ACCESSORS
4602#undef SMI_ACCESSORS
4603#undef ACCESSORS
4604#undef FIELD_ADDR
4605#undef READ_FIELD
4606#undef WRITE_FIELD
4607#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004608#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004609#undef READ_MEMADDR_FIELD
4610#undef WRITE_MEMADDR_FIELD
4611#undef READ_DOUBLE_FIELD
4612#undef WRITE_DOUBLE_FIELD
4613#undef READ_INT_FIELD
4614#undef WRITE_INT_FIELD
4615#undef READ_SHORT_FIELD
4616#undef WRITE_SHORT_FIELD
4617#undef READ_BYTE_FIELD
4618#undef WRITE_BYTE_FIELD
4619
4620
4621} } // namespace v8::internal
4622
4623#endif // V8_OBJECTS_INL_H_