blob: 06c34057bdf56d9973486ec4cc25ee6a06586d46 [file] [log] [blame]
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001// Copyright 2012 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"
danno@chromium.orgfa458e42012-02-01 10:48:36 +000048#include "factory.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000049#include "incremental-marking.h"
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000050#include "transitions-inl.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000051
kasperl@chromium.org71affb52009-05-26 05:44:31 +000052namespace v8 {
53namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000054
55PropertyDetails::PropertyDetails(Smi* smi) {
56 value_ = smi->value();
57}
58
59
60Smi* PropertyDetails::AsSmi() {
61 return Smi::FromInt(value_);
62}
63
64
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000065PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000066 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000067 return PropertyDetails(smi);
68}
69
70
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000071#define TYPE_CHECKER(type, instancetype) \
72 bool Object::Is##type() { \
73 return Object::IsHeapObject() && \
74 HeapObject::cast(this)->map()->instance_type() == instancetype; \
75 }
76
77
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000078#define CAST_ACCESSOR(type) \
79 type* type::cast(Object* object) { \
80 ASSERT(object->Is##type()); \
81 return reinterpret_cast<type*>(object); \
82 }
83
84
85#define INT_ACCESSORS(holder, name, offset) \
86 int holder::name() { return READ_INT_FIELD(this, offset); } \
87 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
88
89
90#define ACCESSORS(holder, name, type, offset) \
91 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000092 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000093 WRITE_FIELD(this, offset, value); \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000094 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000095 }
96
97
rossberg@chromium.org2c067b12012-03-19 11:01:52 +000098// Getter that returns a tagged Smi and setter that writes a tagged Smi.
99#define ACCESSORS_TO_SMI(holder, name, offset) \
100 Smi* holder::name() { return Smi::cast(READ_FIELD(this, offset)); } \
101 void holder::set_##name(Smi* value, WriteBarrierMode mode) { \
102 WRITE_FIELD(this, offset, value); \
103 }
104
105
106// Getter that returns a Smi as an int and writes an int as a Smi.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000107#define SMI_ACCESSORS(holder, name, offset) \
108 int holder::name() { \
109 Object* value = READ_FIELD(this, offset); \
110 return Smi::cast(value)->value(); \
111 } \
112 void holder::set_##name(int value) { \
113 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
114 }
115
116
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000117#define BOOL_GETTER(holder, field, name, offset) \
118 bool holder::name() { \
119 return BooleanBit::get(field(), offset); \
120 } \
121
122
123#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000124 bool holder::name() { \
125 return BooleanBit::get(field(), offset); \
126 } \
127 void holder::set_##name(bool value) { \
128 set_##field(BooleanBit::set(field(), offset, value)); \
129 }
130
131
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000132bool Object::IsFixedArrayBase() {
133 return IsFixedArray() || IsFixedDoubleArray();
134}
135
136
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000137bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
138 // There is a constraint on the object; check.
139 if (!this->IsJSObject()) return false;
140 // Fetch the constructor function of the object.
141 Object* cons_obj = JSObject::cast(this)->map()->constructor();
142 if (!cons_obj->IsJSFunction()) return false;
143 JSFunction* fun = JSFunction::cast(cons_obj);
144 // Iterate through the chain of inheriting function templates to
145 // see if the required one occurs.
146 for (Object* type = fun->shared()->function_data();
147 type->IsFunctionTemplateInfo();
148 type = FunctionTemplateInfo::cast(type)->parent_template()) {
149 if (type == expected) return true;
150 }
151 // Didn't find the required type in the inheritance chain.
152 return false;
153}
154
155
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000156bool Object::IsSmi() {
157 return HAS_SMI_TAG(this);
158}
159
160
161bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000162 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000163}
164
165
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000166bool Object::NonFailureIsHeapObject() {
167 ASSERT(!this->IsFailure());
168 return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0;
169}
170
171
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000172TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000173
174
175bool Object::IsString() {
176 return Object::IsHeapObject()
177 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
178}
179
180
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000181bool Object::IsSpecObject() {
182 return Object::IsHeapObject()
183 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
184}
185
186
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000187bool Object::IsSpecFunction() {
188 if (!Object::IsHeapObject()) return false;
189 InstanceType type = HeapObject::cast(this)->map()->instance_type();
190 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
191}
192
193
ager@chromium.org870a0b62008-11-04 11:43:05 +0000194bool Object::IsSymbol() {
195 if (!this->IsHeapObject()) return false;
196 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000197 // Because the symbol tag is non-zero and no non-string types have the
198 // symbol bit set we can test for symbols with a very simple test
199 // operation.
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000200 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000201 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
202 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000203}
204
205
206bool Object::IsConsString() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000207 if (!IsString()) return false;
208 return StringShape(String::cast(this)).IsCons();
209}
210
211
212bool Object::IsSlicedString() {
213 if (!IsString()) return false;
214 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000215}
216
217
ager@chromium.org870a0b62008-11-04 11:43:05 +0000218bool Object::IsSeqString() {
219 if (!IsString()) return false;
220 return StringShape(String::cast(this)).IsSequential();
221}
222
223
224bool Object::IsSeqAsciiString() {
225 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000226 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000227 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000228}
229
230
231bool Object::IsSeqTwoByteString() {
232 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000233 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000234 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000235}
236
237
238bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000239 if (!IsString()) return false;
240 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000241}
242
243
244bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000245 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000246 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000247 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000248}
249
250
251bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000252 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000253 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000254 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000255}
256
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000257bool Object::HasValidElements() {
258 // Dictionary is covered under FixedArray.
259 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
260}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000261
ager@chromium.org870a0b62008-11-04 11:43:05 +0000262StringShape::StringShape(String* str)
263 : type_(str->map()->instance_type()) {
264 set_valid();
265 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000266}
267
268
ager@chromium.org870a0b62008-11-04 11:43:05 +0000269StringShape::StringShape(Map* map)
270 : type_(map->instance_type()) {
271 set_valid();
272 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000273}
274
275
ager@chromium.org870a0b62008-11-04 11:43:05 +0000276StringShape::StringShape(InstanceType t)
277 : type_(static_cast<uint32_t>(t)) {
278 set_valid();
279 ASSERT((type_ & kIsNotStringMask) == kStringTag);
280}
281
282
283bool StringShape::IsSymbol() {
284 ASSERT(valid());
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000285 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000286 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000287}
288
289
ager@chromium.org5ec48922009-05-05 07:25:34 +0000290bool String::IsAsciiRepresentation() {
291 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000292 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000293}
294
295
ager@chromium.org5ec48922009-05-05 07:25:34 +0000296bool String::IsTwoByteRepresentation() {
297 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000298 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000299}
300
301
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000302bool String::IsAsciiRepresentationUnderneath() {
303 uint32_t type = map()->instance_type();
304 STATIC_ASSERT(kIsIndirectStringTag != 0);
305 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
306 ASSERT(IsFlat());
307 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
308 case kAsciiStringTag:
309 return true;
310 case kTwoByteStringTag:
311 return false;
312 default: // Cons or sliced string. Need to go deeper.
313 return GetUnderlying()->IsAsciiRepresentation();
314 }
315}
316
317
318bool String::IsTwoByteRepresentationUnderneath() {
319 uint32_t type = map()->instance_type();
320 STATIC_ASSERT(kIsIndirectStringTag != 0);
321 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
322 ASSERT(IsFlat());
323 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
324 case kAsciiStringTag:
325 return false;
326 case kTwoByteStringTag:
327 return true;
328 default: // Cons or sliced string. Need to go deeper.
329 return GetUnderlying()->IsTwoByteRepresentation();
330 }
331}
332
333
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000334bool String::HasOnlyAsciiChars() {
335 uint32_t type = map()->instance_type();
336 return (type & kStringEncodingMask) == kAsciiStringTag ||
337 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000338}
339
340
ager@chromium.org870a0b62008-11-04 11:43:05 +0000341bool StringShape::IsCons() {
342 return (type_ & kStringRepresentationMask) == kConsStringTag;
343}
344
345
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000346bool StringShape::IsSliced() {
347 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
348}
349
350
351bool StringShape::IsIndirect() {
352 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
353}
354
355
ager@chromium.org870a0b62008-11-04 11:43:05 +0000356bool StringShape::IsExternal() {
357 return (type_ & kStringRepresentationMask) == kExternalStringTag;
358}
359
360
361bool StringShape::IsSequential() {
362 return (type_ & kStringRepresentationMask) == kSeqStringTag;
363}
364
365
366StringRepresentationTag StringShape::representation_tag() {
367 uint32_t tag = (type_ & kStringRepresentationMask);
368 return static_cast<StringRepresentationTag>(tag);
369}
370
371
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000372uint32_t StringShape::encoding_tag() {
373 return type_ & kStringEncodingMask;
374}
375
376
ager@chromium.org870a0b62008-11-04 11:43:05 +0000377uint32_t StringShape::full_representation_tag() {
378 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
379}
380
381
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000382STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
383 Internals::kFullStringRepresentationMask);
384
385
ager@chromium.org870a0b62008-11-04 11:43:05 +0000386bool StringShape::IsSequentialAscii() {
387 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
388}
389
390
391bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000392 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000393}
394
395
396bool StringShape::IsExternalAscii() {
397 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
398}
399
400
401bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000402 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000403}
404
405
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000406STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
407 Internals::kExternalTwoByteRepresentationTag);
408
409
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000410uc32 FlatStringReader::Get(int index) {
411 ASSERT(0 <= index && index <= length_);
412 if (is_ascii_) {
413 return static_cast<const byte*>(start_)[index];
414 } else {
415 return static_cast<const uc16*>(start_)[index];
416 }
417}
418
419
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000420bool Object::IsNumber() {
421 return IsSmi() || IsHeapNumber();
422}
423
424
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000425TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
426TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000427
428
429bool Object::IsFiller() {
430 if (!Object::IsHeapObject()) return false;
431 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
432 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
433}
434
435
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000436TYPE_CHECKER(ExternalPixelArray, EXTERNAL_PIXEL_ARRAY_TYPE)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000437
438
ager@chromium.org3811b432009-10-28 14:53:37 +0000439bool Object::IsExternalArray() {
440 if (!Object::IsHeapObject())
441 return false;
442 InstanceType instance_type =
443 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000444 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
445 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000446}
447
448
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000449TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE)
450TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
451TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE)
452TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
453TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE)
454TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
455TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE)
456TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000457
458
lrn@chromium.org303ada72010-10-27 09:33:13 +0000459bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000460 return HAS_FAILURE_TAG(this);
461}
462
463
lrn@chromium.org303ada72010-10-27 09:33:13 +0000464bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000465 return HAS_FAILURE_TAG(this)
466 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
467}
468
469
lrn@chromium.org303ada72010-10-27 09:33:13 +0000470bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000471 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000472 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000473}
474
475
lrn@chromium.org303ada72010-10-27 09:33:13 +0000476bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000477 return this == Failure::Exception();
478}
479
480
lrn@chromium.org303ada72010-10-27 09:33:13 +0000481bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000482 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000483}
484
485
486Failure* Failure::cast(MaybeObject* obj) {
487 ASSERT(HAS_FAILURE_TAG(obj));
488 return reinterpret_cast<Failure*>(obj);
489}
490
491
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000492bool Object::IsJSReceiver() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000493 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000494 return IsHeapObject() &&
495 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
496}
497
498
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000499bool Object::IsJSObject() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000500 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
501 return IsHeapObject() &&
502 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000503}
504
505
506bool Object::IsJSProxy() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000507 if (!Object::IsHeapObject()) return false;
508 InstanceType type = HeapObject::cast(this)->map()->instance_type();
509 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000510}
511
512
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000513TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
514TYPE_CHECKER(JSSet, JS_SET_TYPE)
515TYPE_CHECKER(JSMap, JS_MAP_TYPE)
516TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
517TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
518TYPE_CHECKER(Map, MAP_TYPE)
519TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
520TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000521
522
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000523bool Object::IsDescriptorArray() {
524 return IsFixedArray();
525}
526
527
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000528bool Object::IsTransitionArray() {
529 return IsFixedArray();
530}
531
532
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000533bool Object::IsDeoptimizationInputData() {
534 // Must be a fixed array.
535 if (!IsFixedArray()) return false;
536
537 // There's no sure way to detect the difference between a fixed array and
538 // a deoptimization data array. Since this is used for asserts we can
539 // check that the length is zero or else the fixed size plus a multiple of
540 // the entry size.
541 int length = FixedArray::cast(this)->length();
542 if (length == 0) return true;
543
544 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
545 return length >= 0 &&
546 length % DeoptimizationInputData::kDeoptEntrySize == 0;
547}
548
549
550bool Object::IsDeoptimizationOutputData() {
551 if (!IsFixedArray()) return false;
552 // There's actually no way to see the difference between a fixed array and
553 // a deoptimization data array. Since this is used for asserts we can check
554 // that the length is plausible though.
555 if (FixedArray::cast(this)->length() % 2 != 0) return false;
556 return true;
557}
558
559
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000560bool Object::IsTypeFeedbackCells() {
561 if (!IsFixedArray()) return false;
562 // There's actually no way to see the difference between a fixed array and
563 // a cache cells array. Since this is used for asserts we can check that
564 // the length is plausible though.
565 if (FixedArray::cast(this)->length() % 2 != 0) return false;
566 return true;
567}
568
569
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000570bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000571 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000572 Map* map = HeapObject::cast(this)->map();
573 Heap* heap = map->GetHeap();
574 return (map == heap->function_context_map() ||
575 map == heap->catch_context_map() ||
576 map == heap->with_context_map() ||
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000577 map == heap->global_context_map() ||
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000578 map == heap->block_context_map() ||
579 map == heap->module_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000580 }
581 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000582}
583
584
585bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000586 return Object::IsHeapObject() &&
587 HeapObject::cast(this)->map() ==
588 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000589}
590
591
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000592bool Object::IsModuleContext() {
593 return Object::IsHeapObject() &&
594 HeapObject::cast(this)->map() ==
595 HeapObject::cast(this)->GetHeap()->module_context_map();
596}
597
598
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000599bool Object::IsScopeInfo() {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000600 return Object::IsHeapObject() &&
601 HeapObject::cast(this)->map() ==
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000602 HeapObject::cast(this)->GetHeap()->scope_info_map();
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000603}
604
605
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000606TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000607
608
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000609template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000610 return obj->IsJSFunction();
611}
612
613
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000614TYPE_CHECKER(Code, CODE_TYPE)
615TYPE_CHECKER(Oddball, ODDBALL_TYPE)
616TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
617TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000618TYPE_CHECKER(JSModule, JS_MODULE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000619TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000620TYPE_CHECKER(JSDate, JS_DATE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000621TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000622
623
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000624bool Object::IsStringWrapper() {
625 return IsJSValue() && JSValue::cast(this)->value()->IsString();
626}
627
628
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000629TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000630
631
632bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000633 return IsOddball() &&
634 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000635}
636
637
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000638TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
639TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000640
641
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000642template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000643 return obj->IsJSArray();
644}
645
646
647bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000648 return Object::IsHeapObject() &&
649 HeapObject::cast(this)->map() ==
650 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000651}
652
653
654bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000655 return IsHashTable() &&
656 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000657}
658
659
660bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000661 return IsHashTable() && this ==
662 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000663}
664
665
ager@chromium.orgac091b72010-05-05 07:34:42 +0000666bool Object::IsJSFunctionResultCache() {
667 if (!IsFixedArray()) return false;
668 FixedArray* self = FixedArray::cast(this);
669 int length = self->length();
670 if (length < JSFunctionResultCache::kEntriesIndex) return false;
671 if ((length - JSFunctionResultCache::kEntriesIndex)
672 % JSFunctionResultCache::kEntrySize != 0) {
673 return false;
674 }
675#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000676 if (FLAG_verify_heap) {
677 reinterpret_cast<JSFunctionResultCache*>(this)->
678 JSFunctionResultCacheVerify();
679 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000680#endif
681 return true;
682}
683
684
ricow@chromium.org65fae842010-08-25 15:26:24 +0000685bool Object::IsNormalizedMapCache() {
686 if (!IsFixedArray()) return false;
687 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
688 return false;
689 }
690#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000691 if (FLAG_verify_heap) {
692 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
693 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000694#endif
695 return true;
696}
697
698
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000699bool Object::IsCompilationCacheTable() {
700 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000701}
702
703
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000704bool Object::IsCodeCacheHashTable() {
705 return IsHashTable();
706}
707
708
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000709bool Object::IsPolymorphicCodeCacheHashTable() {
710 return IsHashTable();
711}
712
713
ager@chromium.org236ad962008-09-25 09:45:57 +0000714bool Object::IsMapCache() {
715 return IsHashTable();
716}
717
718
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000719bool Object::IsPrimitive() {
720 return IsOddball() || IsNumber() || IsString();
721}
722
723
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000724bool Object::IsJSGlobalProxy() {
725 bool result = IsHeapObject() &&
726 (HeapObject::cast(this)->map()->instance_type() ==
727 JS_GLOBAL_PROXY_TYPE);
728 ASSERT(!result || IsAccessCheckNeeded());
729 return result;
730}
731
732
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000733bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000734 if (!IsHeapObject()) return false;
735
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000736 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000737 return type == JS_GLOBAL_OBJECT_TYPE ||
738 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000739}
740
741
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000742TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
743TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000744
745
746bool Object::IsUndetectableObject() {
747 return IsHeapObject()
748 && HeapObject::cast(this)->map()->is_undetectable();
749}
750
751
752bool Object::IsAccessCheckNeeded() {
753 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000754 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000755}
756
757
758bool Object::IsStruct() {
759 if (!IsHeapObject()) return false;
760 switch (HeapObject::cast(this)->map()->instance_type()) {
761#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
762 STRUCT_LIST(MAKE_STRUCT_CASE)
763#undef MAKE_STRUCT_CASE
764 default: return false;
765 }
766}
767
768
769#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
770 bool Object::Is##Name() { \
771 return Object::IsHeapObject() \
772 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
773 }
774 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
775#undef MAKE_STRUCT_PREDICATE
776
777
778bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000779 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000780}
781
782
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000783bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000784 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
785}
786
787
788bool Object::IsTheHole() {
789 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000790}
791
792
793bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000794 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000795}
796
797
798bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000799 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000800}
801
802
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000803bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000804 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000805}
806
807
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000808double Object::Number() {
809 ASSERT(IsNumber());
810 return IsSmi()
811 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
812 : reinterpret_cast<HeapNumber*>(this)->value();
813}
814
815
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000816bool Object::IsNaN() {
817 return this->IsHeapNumber() && isnan(HeapNumber::cast(this)->value());
818}
819
820
lrn@chromium.org303ada72010-10-27 09:33:13 +0000821MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000822 if (IsSmi()) return this;
823 if (IsHeapNumber()) {
824 double value = HeapNumber::cast(this)->value();
825 int int_value = FastD2I(value);
826 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
827 return Smi::FromInt(int_value);
828 }
829 }
830 return Failure::Exception();
831}
832
833
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000834bool Object::HasSpecificClassOf(String* name) {
835 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
836}
837
838
lrn@chromium.org303ada72010-10-27 09:33:13 +0000839MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000840 // GetElement can trigger a getter which can cause allocation.
841 // This was not always the case. This ASSERT is here to catch
842 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000843 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000844 return GetElementWithReceiver(this, index);
845}
846
847
lrn@chromium.org303ada72010-10-27 09:33:13 +0000848Object* Object::GetElementNoExceptionThrown(uint32_t index) {
849 MaybeObject* maybe = GetElementWithReceiver(this, index);
850 ASSERT(!maybe->IsFailure());
851 Object* result = NULL; // Initialization to please compiler.
852 maybe->ToObject(&result);
853 return result;
854}
855
856
857MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000858 PropertyAttributes attributes;
859 return GetPropertyWithReceiver(this, key, &attributes);
860}
861
862
lrn@chromium.org303ada72010-10-27 09:33:13 +0000863MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000864 return GetPropertyWithReceiver(this, key, attributes);
865}
866
867
868#define FIELD_ADDR(p, offset) \
869 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
870
871#define READ_FIELD(p, offset) \
872 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
873
874#define WRITE_FIELD(p, offset, value) \
875 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
876
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000877#define WRITE_BARRIER(heap, object, offset, value) \
878 heap->incremental_marking()->RecordWrite( \
879 object, HeapObject::RawField(object, offset), value); \
880 if (heap->InNewSpace(value)) { \
881 heap->RecordWrite(object->address(), offset); \
882 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000883
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000884#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
885 if (mode == UPDATE_WRITE_BARRIER) { \
886 heap->incremental_marking()->RecordWrite( \
887 object, HeapObject::RawField(object, offset), value); \
888 if (heap->InNewSpace(value)) { \
889 heap->RecordWrite(object->address(), offset); \
890 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000891 }
892
lrn@chromium.org7516f052011-03-30 08:52:27 +0000893#ifndef V8_TARGET_ARCH_MIPS
894 #define READ_DOUBLE_FIELD(p, offset) \
895 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
896#else // V8_TARGET_ARCH_MIPS
897 // Prevent gcc from using load-double (mips ldc1) on (possibly)
898 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000899 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000900 union conversion {
901 double d;
902 uint32_t u[2];
903 } c;
904 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
905 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
906 return c.d;
907 }
908 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
909#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000910
lrn@chromium.org7516f052011-03-30 08:52:27 +0000911#ifndef V8_TARGET_ARCH_MIPS
912 #define WRITE_DOUBLE_FIELD(p, offset, value) \
913 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
914#else // V8_TARGET_ARCH_MIPS
915 // Prevent gcc from using store-double (mips sdc1) on (possibly)
916 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000917 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000918 double value) {
919 union conversion {
920 double d;
921 uint32_t u[2];
922 } c;
923 c.d = value;
924 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
925 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
926 }
927 #define WRITE_DOUBLE_FIELD(p, offset, value) \
928 write_double_field(p, offset, value)
929#endif // V8_TARGET_ARCH_MIPS
930
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000931
932#define READ_INT_FIELD(p, offset) \
933 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
934
935#define WRITE_INT_FIELD(p, offset, value) \
936 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
937
ager@chromium.org3e875802009-06-29 08:26:34 +0000938#define READ_INTPTR_FIELD(p, offset) \
939 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
940
941#define WRITE_INTPTR_FIELD(p, offset, value) \
942 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
943
ager@chromium.org7c537e22008-10-16 08:43:32 +0000944#define READ_UINT32_FIELD(p, offset) \
945 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
946
947#define WRITE_UINT32_FIELD(p, offset, value) \
948 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
949
danno@chromium.org88aa0582012-03-23 15:11:57 +0000950#define READ_INT64_FIELD(p, offset) \
951 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)))
952
953#define WRITE_INT64_FIELD(p, offset, value) \
954 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
955
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000956#define READ_SHORT_FIELD(p, offset) \
957 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
958
959#define WRITE_SHORT_FIELD(p, offset, value) \
960 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
961
962#define READ_BYTE_FIELD(p, offset) \
963 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
964
965#define WRITE_BYTE_FIELD(p, offset, value) \
966 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
967
968
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000969Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
970 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000971}
972
973
974int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000975 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000976}
977
978
979Smi* Smi::FromInt(int value) {
980 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000981 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000982 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000983 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000984 return reinterpret_cast<Smi*>(tagged_value);
985}
986
987
988Smi* Smi::FromIntptr(intptr_t value) {
989 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000990 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
991 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000992}
993
994
995Failure::Type Failure::type() const {
996 return static_cast<Type>(value() & kFailureTypeTagMask);
997}
998
999
1000bool Failure::IsInternalError() const {
1001 return type() == INTERNAL_ERROR;
1002}
1003
1004
1005bool Failure::IsOutOfMemoryException() const {
1006 return type() == OUT_OF_MEMORY_EXCEPTION;
1007}
1008
1009
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001010AllocationSpace Failure::allocation_space() const {
1011 ASSERT_EQ(RETRY_AFTER_GC, type());
1012 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1013 & kSpaceTagMask);
1014}
1015
1016
1017Failure* Failure::InternalError() {
1018 return Construct(INTERNAL_ERROR);
1019}
1020
1021
1022Failure* Failure::Exception() {
1023 return Construct(EXCEPTION);
1024}
1025
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001026
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001027Failure* Failure::OutOfMemoryException() {
1028 return Construct(OUT_OF_MEMORY_EXCEPTION);
1029}
1030
1031
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001032intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001033 return static_cast<intptr_t>(
1034 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001035}
1036
1037
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001038Failure* Failure::RetryAfterGC() {
1039 return RetryAfterGC(NEW_SPACE);
1040}
1041
1042
1043Failure* Failure::RetryAfterGC(AllocationSpace space) {
1044 ASSERT((space & ~kSpaceTagMask) == 0);
1045 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001046}
1047
1048
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001049Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001050 uintptr_t info =
1051 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001052 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001053 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001054}
1055
1056
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001057bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001058#ifdef DEBUG
1059 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1060#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001061
1062#ifdef V8_TARGET_ARCH_X64
1063 // To be representable as a long smi, the value must be a 32-bit integer.
1064 bool result = (value == static_cast<int32_t>(value));
1065#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001066 // To be representable as an tagged small integer, the two
1067 // most-significant bits of 'value' must be either 00 or 11 due to
1068 // sign-extension. To check this we add 01 to the two
1069 // most-significant bits, and check if the most-significant bit is 0
1070 //
1071 // CAUTION: The original code below:
1072 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1073 // may lead to incorrect results according to the C language spec, and
1074 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1075 // compiler may produce undefined results in case of signed integer
1076 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001077 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001078#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001079 ASSERT(result == in_range);
1080 return result;
1081}
1082
1083
kasper.lund7276f142008-07-30 08:49:36 +00001084MapWord MapWord::FromMap(Map* map) {
1085 return MapWord(reinterpret_cast<uintptr_t>(map));
1086}
1087
1088
1089Map* MapWord::ToMap() {
1090 return reinterpret_cast<Map*>(value_);
1091}
1092
1093
1094bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001095 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001096}
1097
1098
1099MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001100 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1101 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001102}
1103
1104
1105HeapObject* MapWord::ToForwardingAddress() {
1106 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001107 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001108}
1109
1110
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001111#ifdef DEBUG
1112void HeapObject::VerifyObjectField(int offset) {
1113 VerifyPointer(READ_FIELD(this, offset));
1114}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001115
1116void HeapObject::VerifySmiField(int offset) {
1117 ASSERT(READ_FIELD(this, offset)->IsSmi());
1118}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001119#endif
1120
1121
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001122Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001123 Heap* heap =
1124 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1125 ASSERT(heap != NULL);
1126 ASSERT(heap->isolate() == Isolate::Current());
1127 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001128}
1129
1130
1131Isolate* HeapObject::GetIsolate() {
1132 return GetHeap()->isolate();
1133}
1134
1135
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001136Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001137 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001138}
1139
1140
1141void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001142 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001143 if (value != NULL) {
1144 // TODO(1600) We are passing NULL as a slot because maps can never be on
1145 // evacuation candidate.
1146 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1147 }
1148}
1149
1150
1151// Unsafe accessor omitting write barrier.
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001152void HeapObject::set_map_no_write_barrier(Map* value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001153 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001154}
1155
1156
kasper.lund7276f142008-07-30 08:49:36 +00001157MapWord HeapObject::map_word() {
1158 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1159}
1160
1161
1162void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001163 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001164 // here.
1165 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1166}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001167
1168
1169HeapObject* HeapObject::FromAddress(Address address) {
1170 ASSERT_TAG_ALIGNED(address);
1171 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1172}
1173
1174
1175Address HeapObject::address() {
1176 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1177}
1178
1179
1180int HeapObject::Size() {
1181 return SizeFromMap(map());
1182}
1183
1184
1185void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1186 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1187 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1188}
1189
1190
1191void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1192 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1193}
1194
1195
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001196double HeapNumber::value() {
1197 return READ_DOUBLE_FIELD(this, kValueOffset);
1198}
1199
1200
1201void HeapNumber::set_value(double value) {
1202 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1203}
1204
1205
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001206int HeapNumber::get_exponent() {
1207 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1208 kExponentShift) - kExponentBias;
1209}
1210
1211
1212int HeapNumber::get_sign() {
1213 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1214}
1215
1216
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001217ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001218
1219
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001220Object** FixedArray::GetFirstElementAddress() {
1221 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1222}
1223
1224
1225bool FixedArray::ContainsOnlySmisOrHoles() {
1226 Object* the_hole = GetHeap()->the_hole_value();
1227 Object** current = GetFirstElementAddress();
1228 for (int i = 0; i < length(); ++i) {
1229 Object* candidate = *current++;
1230 if (!candidate->IsSmi() && candidate != the_hole) return false;
1231 }
1232 return true;
1233}
1234
1235
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001236FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001237 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001238 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001239}
1240
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001241
1242void JSObject::ValidateElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001243#if DEBUG
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001244 if (FLAG_enable_slow_asserts) {
1245 ElementsAccessor* accessor = GetElementsAccessor();
1246 accessor->Validate(this);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001247 }
1248#endif
1249}
1250
1251
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001252MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001253 ValidateElements();
1254 ElementsKind elements_kind = map()->elements_kind();
1255 if (!IsFastObjectElementsKind(elements_kind)) {
1256 if (IsFastHoleyElementsKind(elements_kind)) {
1257 return TransitionElementsKind(FAST_HOLEY_ELEMENTS);
1258 } else {
1259 return TransitionElementsKind(FAST_ELEMENTS);
1260 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001261 }
1262 return this;
1263}
1264
1265
1266MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001267 uint32_t count,
1268 EnsureElementsMode mode) {
1269 ElementsKind current_kind = map()->elements_kind();
1270 ElementsKind target_kind = current_kind;
1271 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001272 bool is_holey = IsFastHoleyElementsKind(current_kind);
1273 if (current_kind == FAST_HOLEY_ELEMENTS) return this;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001274 Heap* heap = GetHeap();
1275 Object* the_hole = heap->the_hole_value();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001276 for (uint32_t i = 0; i < count; ++i) {
1277 Object* current = *objects++;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001278 if (current == the_hole) {
1279 is_holey = true;
1280 target_kind = GetHoleyElementsKind(target_kind);
1281 } else if (!current->IsSmi()) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001282 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && current->IsNumber()) {
1283 if (IsFastSmiElementsKind(target_kind)) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001284 if (is_holey) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001285 target_kind = FAST_HOLEY_DOUBLE_ELEMENTS;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001286 } else {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001287 target_kind = FAST_DOUBLE_ELEMENTS;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001288 }
1289 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001290 } else if (is_holey) {
1291 target_kind = FAST_HOLEY_ELEMENTS;
1292 break;
1293 } else {
1294 target_kind = FAST_ELEMENTS;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001295 }
1296 }
1297 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001298
1299 if (target_kind != current_kind) {
1300 return TransitionElementsKind(target_kind);
1301 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001302 return this;
1303}
1304
1305
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001306MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001307 uint32_t length,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001308 EnsureElementsMode mode) {
1309 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1310 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1311 elements->map() == GetHeap()->fixed_cow_array_map());
1312 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1313 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1314 }
1315 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001316 return EnsureCanContainElements(objects, length, mode);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001317 }
1318
1319 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001320 if (GetElementsKind() == FAST_HOLEY_SMI_ELEMENTS) {
1321 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS);
1322 } else if (GetElementsKind() == FAST_SMI_ELEMENTS) {
1323 FixedDoubleArray* double_array = FixedDoubleArray::cast(elements);
1324 for (uint32_t i = 0; i < length; ++i) {
1325 if (double_array->is_the_hole(i)) {
1326 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS);
1327 }
1328 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001329 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1330 }
1331
1332 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001333}
1334
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001335
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001336MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
1337 ElementsKind to_kind) {
1338 Map* current_map = map();
1339 ElementsKind from_kind = current_map->elements_kind();
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001340 if (from_kind == to_kind) return current_map;
1341
1342 Context* global_context = isolate->context()->global_context();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001343 Object* maybe_array_maps = global_context->js_array_maps();
1344 if (maybe_array_maps->IsFixedArray()) {
1345 FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
1346 if (array_maps->get(from_kind) == current_map) {
1347 Object* maybe_transitioned_map = array_maps->get(to_kind);
1348 if (maybe_transitioned_map->IsMap()) {
1349 return Map::cast(maybe_transitioned_map);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001350 }
1351 }
1352 }
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001353
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001354 return GetElementsTransitionMapSlow(to_kind);
1355}
1356
1357
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001358void JSObject::set_map_and_elements(Map* new_map,
1359 FixedArrayBase* value,
1360 WriteBarrierMode mode) {
1361 ASSERT(value->HasValidElements());
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001362 if (new_map != NULL) {
1363 if (mode == UPDATE_WRITE_BARRIER) {
1364 set_map(new_map);
1365 } else {
1366 ASSERT(mode == SKIP_WRITE_BARRIER);
1367 set_map_no_write_barrier(new_map);
1368 }
1369 }
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001370 ASSERT((map()->has_fast_smi_or_object_elements() ||
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001371 (value == GetHeap()->empty_fixed_array())) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001372 (value->map() == GetHeap()->fixed_array_map() ||
1373 value->map() == GetHeap()->fixed_cow_array_map()));
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001374 ASSERT((value == GetHeap()->empty_fixed_array()) ||
1375 (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001376 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001377 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001378}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001379
1380
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001381void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1382 set_map_and_elements(NULL, value, mode);
1383}
1384
1385
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001386void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001387 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1388 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001389}
1390
1391
1392void JSObject::initialize_elements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001393 ASSERT(map()->has_fast_smi_or_object_elements() ||
danno@chromium.org2c26cb12012-05-03 09:06:43 +00001394 map()->has_fast_double_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001395 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1396 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001397}
1398
1399
lrn@chromium.org303ada72010-10-27 09:33:13 +00001400MaybeObject* JSObject::ResetElements() {
1401 Object* obj;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001402 ElementsKind elements_kind = GetInitialFastElementsKind();
1403 if (!FLAG_smi_only_arrays) {
1404 elements_kind = FastSmiToObjectElementsKind(elements_kind);
1405 }
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001406 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(),
1407 elements_kind);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001408 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001409 set_map(Map::cast(obj));
1410 initialize_elements();
1411 return this;
1412}
1413
1414
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001415ACCESSORS(Oddball, to_string, String, kToStringOffset)
1416ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1417
1418
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001419byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001420 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001421}
1422
1423
1424void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001425 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001426}
1427
1428
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001429Object* JSGlobalPropertyCell::value() {
1430 return READ_FIELD(this, kValueOffset);
1431}
1432
1433
1434void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1435 // The write barrier is not used for global property cells.
1436 ASSERT(!val->IsJSGlobalPropertyCell());
1437 WRITE_FIELD(this, kValueOffset, val);
1438}
1439
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001440
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001441int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001442 InstanceType type = map()->instance_type();
1443 // Check for the most common kind of JavaScript object before
1444 // falling into the generic switch. This speeds up the internal
1445 // field operations considerably on average.
1446 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1447 switch (type) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001448 case JS_MODULE_TYPE:
1449 return JSModule::kSize;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001450 case JS_GLOBAL_PROXY_TYPE:
1451 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001452 case JS_GLOBAL_OBJECT_TYPE:
1453 return JSGlobalObject::kSize;
1454 case JS_BUILTINS_OBJECT_TYPE:
1455 return JSBuiltinsObject::kSize;
1456 case JS_FUNCTION_TYPE:
1457 return JSFunction::kSize;
1458 case JS_VALUE_TYPE:
1459 return JSValue::kSize;
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00001460 case JS_DATE_TYPE:
1461 return JSDate::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001462 case JS_ARRAY_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001463 return JSArray::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001464 case JS_WEAK_MAP_TYPE:
1465 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001466 case JS_REGEXP_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001467 return JSRegExp::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001468 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001469 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001470 case JS_MESSAGE_OBJECT_TYPE:
1471 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001472 default:
1473 UNREACHABLE();
1474 return 0;
1475 }
1476}
1477
1478
1479int JSObject::GetInternalFieldCount() {
1480 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001481 // Make sure to adjust for the number of in-object properties. These
1482 // properties do contribute to the size, but are not internal fields.
1483 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1484 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001485}
1486
1487
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001488int JSObject::GetInternalFieldOffset(int index) {
1489 ASSERT(index < GetInternalFieldCount() && index >= 0);
1490 return GetHeaderSize() + (kPointerSize * index);
1491}
1492
1493
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001494Object* JSObject::GetInternalField(int index) {
1495 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001496 // Internal objects do follow immediately after the header, whereas in-object
1497 // properties are at the end of the object. Therefore there is no need
1498 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001499 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1500}
1501
1502
1503void JSObject::SetInternalField(int index, Object* value) {
1504 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001505 // Internal objects do follow immediately after the header, whereas in-object
1506 // properties are at the end of the object. Therefore there is no need
1507 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001508 int offset = GetHeaderSize() + (kPointerSize * index);
1509 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001510 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001511}
1512
1513
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001514void JSObject::SetInternalField(int index, Smi* value) {
1515 ASSERT(index < GetInternalFieldCount() && index >= 0);
1516 // Internal objects do follow immediately after the header, whereas in-object
1517 // properties are at the end of the object. Therefore there is no need
1518 // to adjust the index here.
1519 int offset = GetHeaderSize() + (kPointerSize * index);
1520 WRITE_FIELD(this, offset, value);
1521}
1522
1523
ager@chromium.org7c537e22008-10-16 08:43:32 +00001524// Access fast-case object properties at index. The use of these routines
1525// is needed to correctly distinguish between properties stored in-object and
1526// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001527Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001528 // Adjust for the number of properties stored in the object.
1529 index -= map()->inobject_properties();
1530 if (index < 0) {
1531 int offset = map()->instance_size() + (index * kPointerSize);
1532 return READ_FIELD(this, offset);
1533 } else {
1534 ASSERT(index < properties()->length());
1535 return properties()->get(index);
1536 }
1537}
1538
1539
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001540Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001541 // Adjust for the number of properties stored in the object.
1542 index -= map()->inobject_properties();
1543 if (index < 0) {
1544 int offset = map()->instance_size() + (index * kPointerSize);
1545 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001546 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001547 } else {
1548 ASSERT(index < properties()->length());
1549 properties()->set(index, value);
1550 }
1551 return value;
1552}
1553
1554
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001555int JSObject::GetInObjectPropertyOffset(int index) {
1556 // Adjust for the number of properties stored in the object.
1557 index -= map()->inobject_properties();
1558 ASSERT(index < 0);
1559 return map()->instance_size() + (index * kPointerSize);
1560}
1561
1562
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001563Object* JSObject::InObjectPropertyAt(int index) {
1564 // Adjust for the number of properties stored in the object.
1565 index -= map()->inobject_properties();
1566 ASSERT(index < 0);
1567 int offset = map()->instance_size() + (index * kPointerSize);
1568 return READ_FIELD(this, offset);
1569}
1570
1571
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001572Object* JSObject::InObjectPropertyAtPut(int index,
1573 Object* value,
1574 WriteBarrierMode mode) {
1575 // Adjust for the number of properties stored in the object.
1576 index -= map()->inobject_properties();
1577 ASSERT(index < 0);
1578 int offset = map()->instance_size() + (index * kPointerSize);
1579 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001580 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001581 return value;
1582}
1583
1584
1585
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001586void JSObject::InitializeBody(Map* map,
1587 Object* pre_allocated_value,
1588 Object* filler_value) {
1589 ASSERT(!filler_value->IsHeapObject() ||
1590 !GetHeap()->InNewSpace(filler_value));
1591 ASSERT(!pre_allocated_value->IsHeapObject() ||
1592 !GetHeap()->InNewSpace(pre_allocated_value));
1593 int size = map->instance_size();
1594 int offset = kHeaderSize;
1595 if (filler_value != pre_allocated_value) {
1596 int pre_allocated = map->pre_allocated_property_fields();
1597 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1598 for (int i = 0; i < pre_allocated; i++) {
1599 WRITE_FIELD(this, offset, pre_allocated_value);
1600 offset += kPointerSize;
1601 }
1602 }
1603 while (offset < size) {
1604 WRITE_FIELD(this, offset, filler_value);
1605 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001606 }
1607}
1608
1609
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001610bool JSObject::HasFastProperties() {
1611 return !properties()->IsDictionary();
1612}
1613
1614
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001615bool JSObject::TooManyFastProperties(int properties,
1616 JSObject::StoreFromKeyed store_mode) {
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001617 // Allow extra fast properties if the object has more than
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001618 // kFastPropertiesSoftLimit in-object properties. When this is the case,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001619 // it is very unlikely that the object is being used as a dictionary
1620 // and there is a good chance that allowing more map transitions
1621 // will be worth it.
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001622 int inobject = map()->inobject_properties();
1623
1624 int limit;
ulan@chromium.orgf6a0c412012-06-15 12:31:06 +00001625 if (store_mode == CERTAINLY_NOT_STORE_FROM_KEYED) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001626 limit = Max(inobject, kMaxFastProperties);
1627 } else {
1628 limit = Max(inobject, kFastPropertiesSoftLimit);
1629 }
1630 return properties > limit;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001631}
1632
1633
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001634void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001635 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001636 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001637 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001638 }
1639}
1640
1641
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001642bool Object::ToArrayIndex(uint32_t* index) {
1643 if (IsSmi()) {
1644 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001645 if (value < 0) return false;
1646 *index = value;
1647 return true;
1648 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001649 if (IsHeapNumber()) {
1650 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001651 uint32_t uint_value = static_cast<uint32_t>(value);
1652 if (value == static_cast<double>(uint_value)) {
1653 *index = uint_value;
1654 return true;
1655 }
1656 }
1657 return false;
1658}
1659
1660
1661bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1662 if (!this->IsJSValue()) return false;
1663
1664 JSValue* js_value = JSValue::cast(this);
1665 if (!js_value->value()->IsString()) return false;
1666
1667 String* str = String::cast(js_value->value());
1668 if (index >= (uint32_t)str->length()) return false;
1669
1670 return true;
1671}
1672
1673
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001674FixedArrayBase* FixedArrayBase::cast(Object* object) {
1675 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1676 return reinterpret_cast<FixedArrayBase*>(object);
1677}
1678
1679
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001680Object* FixedArray::get(int index) {
1681 ASSERT(index >= 0 && index < this->length());
1682 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1683}
1684
1685
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001686bool FixedArray::is_the_hole(int index) {
1687 return get(index) == GetHeap()->the_hole_value();
1688}
1689
1690
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001691void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001692 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001693 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001694 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1695 int offset = kHeaderSize + index * kPointerSize;
1696 WRITE_FIELD(this, offset, value);
1697}
1698
1699
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001700void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001701 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001702 ASSERT(index >= 0 && index < this->length());
1703 int offset = kHeaderSize + index * kPointerSize;
1704 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001705 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001706}
1707
1708
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001709inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1710 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1711}
1712
1713
1714inline double FixedDoubleArray::hole_nan_as_double() {
1715 return BitCast<double, uint64_t>(kHoleNanInt64);
1716}
1717
1718
1719inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1720 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1721 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1722 return OS::nan_value();
1723}
1724
1725
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001726double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001727 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1728 map() != HEAP->fixed_array_map());
1729 ASSERT(index >= 0 && index < this->length());
1730 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1731 ASSERT(!is_the_hole_nan(result));
1732 return result;
1733}
1734
danno@chromium.org88aa0582012-03-23 15:11:57 +00001735int64_t FixedDoubleArray::get_representation(int index) {
1736 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1737 map() != HEAP->fixed_array_map());
1738 ASSERT(index >= 0 && index < this->length());
1739 return READ_INT64_FIELD(this, kHeaderSize + index * kDoubleSize);
1740}
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001741
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001742MaybeObject* FixedDoubleArray::get(int index) {
1743 if (is_the_hole(index)) {
1744 return GetHeap()->the_hole_value();
1745 } else {
1746 return GetHeap()->NumberFromDouble(get_scalar(index));
1747 }
1748}
1749
1750
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001751void FixedDoubleArray::set(int index, double value) {
1752 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1753 map() != HEAP->fixed_array_map());
1754 int offset = kHeaderSize + index * kDoubleSize;
1755 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1756 WRITE_DOUBLE_FIELD(this, offset, value);
1757}
1758
1759
1760void FixedDoubleArray::set_the_hole(int index) {
1761 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1762 map() != HEAP->fixed_array_map());
1763 int offset = kHeaderSize + index * kDoubleSize;
1764 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1765}
1766
1767
1768bool FixedDoubleArray::is_the_hole(int index) {
1769 int offset = kHeaderSize + index * kDoubleSize;
1770 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1771}
1772
1773
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001774WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001775 Heap* heap = GetHeap();
1776 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1777 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001778 return UPDATE_WRITE_BARRIER;
1779}
1780
1781
1782void FixedArray::set(int index,
1783 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001784 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001785 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001786 ASSERT(index >= 0 && index < this->length());
1787 int offset = kHeaderSize + index * kPointerSize;
1788 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001789 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001790}
1791
1792
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001793void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1794 int index,
1795 Object* value) {
1796 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
1797 ASSERT(index >= 0 && index < array->length());
1798 int offset = kHeaderSize + index * kPointerSize;
1799 WRITE_FIELD(array, offset, value);
1800 Heap* heap = array->GetHeap();
1801 if (heap->InNewSpace(value)) {
1802 heap->RecordWrite(array->address(), offset);
1803 }
1804}
1805
1806
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001807void FixedArray::NoWriteBarrierSet(FixedArray* array,
1808 int index,
1809 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001810 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001811 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001812 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001813 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1814}
1815
1816
1817void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001818 ASSERT(map() != HEAP->fixed_cow_array_map());
1819 set_undefined(GetHeap(), index);
1820}
1821
1822
1823void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001824 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001825 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001826 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001827 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001828}
1829
1830
ager@chromium.org236ad962008-09-25 09:45:57 +00001831void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001832 set_null(GetHeap(), index);
1833}
1834
1835
1836void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001837 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001838 ASSERT(!heap->InNewSpace(heap->null_value()));
1839 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001840}
1841
1842
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001843void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001844 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001845 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001846 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1847 WRITE_FIELD(this,
1848 kHeaderSize + index * kPointerSize,
1849 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001850}
1851
1852
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001853void FixedArray::set_unchecked(int index, Smi* value) {
1854 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1855 int offset = kHeaderSize + index * kPointerSize;
1856 WRITE_FIELD(this, offset, value);
1857}
1858
1859
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001860void FixedArray::set_unchecked(Heap* heap,
1861 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001862 Object* value,
1863 WriteBarrierMode mode) {
1864 int offset = kHeaderSize + index * kPointerSize;
1865 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001866 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001867}
1868
1869
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001870void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001871 ASSERT(index >= 0 && index < this->length());
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00001872 ASSERT(!heap->InNewSpace(heap->null_value()));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001873 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001874}
1875
1876
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001877Object** FixedArray::data_start() {
1878 return HeapObject::RawField(this, kHeaderSize);
1879}
1880
1881
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001882bool DescriptorArray::IsEmpty() {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001883 ASSERT(length() >= kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001884 this == HEAP->empty_descriptor_array());
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001885 return length() < kFirstIndex;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001886}
1887
1888
1889bool DescriptorArray::MayContainTransitions() {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001890 return !IsEmpty();
danno@chromium.org40cb8782011-05-25 07:58:50 +00001891}
1892
1893
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001894bool DescriptorArray::HasTransitionArray() {
1895 return MayContainTransitions() && !get(kTransitionsIndex)->IsSmi();
1896}
1897
1898
danno@chromium.org40cb8782011-05-25 07:58:50 +00001899int DescriptorArray::bit_field3_storage() {
1900 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1901 return Smi::cast(storage)->value();
1902}
1903
1904void DescriptorArray::set_bit_field3_storage(int value) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001905 ASSERT(length() > kBitField3StorageIndex);
danno@chromium.org40cb8782011-05-25 07:58:50 +00001906 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001907}
1908
1909
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001910void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1911 int first,
1912 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001913 Object* tmp = array->get(first);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001914 NoIncrementalWriteBarrierSet(array, first, array->get(second));
1915 NoIncrementalWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001916}
1917
1918
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001919// Perform a binary search in a fixed array. Low and high are entry indices. If
1920// there are three entries in this array it should be called with low=0 and
1921// high=2.
1922template<typename T>
1923int BinarySearch(T* array, String* name, int low, int high) {
1924 uint32_t hash = name->Hash();
1925 int limit = high;
1926
1927 ASSERT(low <= high);
1928
1929 while (low != high) {
1930 int mid = (low + high) / 2;
1931 String* mid_name = array->GetKey(mid);
1932 uint32_t mid_hash = mid_name->Hash();
1933
1934 if (mid_hash >= hash) {
1935 high = mid;
1936 } else {
1937 low = mid + 1;
1938 }
1939 }
1940
1941 for (; low <= limit && array->GetKey(low)->Hash() == hash; ++low) {
1942 if (array->GetKey(low)->Equals(name)) return low;
1943 }
1944
1945 return T::kNotFound;
1946}
1947
1948
1949// Perform a linear search in this fixed array. len is the number of entry
1950// indices that are valid.
1951template<typename T>
1952int LinearSearch(T* array, SearchMode mode, String* name, int len) {
1953 uint32_t hash = name->Hash();
1954 for (int number = 0; number < len; number++) {
1955 String* entry = array->GetKey(number);
1956 uint32_t current_hash = entry->Hash();
1957 if (mode == EXPECT_SORTED && current_hash > hash) break;
1958 if (current_hash == hash && name->Equals(entry)) return number;
1959 }
1960 return T::kNotFound;
1961}
1962
1963
1964template<typename T>
1965int Search(T* array, String* name) {
1966 SLOW_ASSERT(array->IsSortedNoDuplicates());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001967
1968 // Check for empty descriptor array.
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001969 int nof = array->number_of_entries();
1970 if (nof == 0) return T::kNotFound;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001971
1972 // Fast case: do linear search for small arrays.
1973 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001974 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001975 return LinearSearch(array, EXPECT_SORTED, name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001976 }
1977
1978 // Slow case: perform binary search.
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001979 return BinarySearch(array, name, 0, nof - 1);
1980}
1981
1982
1983int DescriptorArray::Search(String* name) {
1984 return internal::Search(this, name);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001985}
1986
1987
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001988int DescriptorArray::SearchWithCache(String* name) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001989 DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache();
1990 int number = cache->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001991 if (number == DescriptorLookupCache::kAbsent) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001992 number = internal::Search(this, name);
1993 cache->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001994 }
1995 return number;
1996}
1997
1998
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001999TransitionArray* DescriptorArray::transitions() {
2000 ASSERT(MayContainTransitions());
2001 Object* array = get(kTransitionsIndex);
2002 return TransitionArray::cast(array);
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002003}
2004
2005
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002006void DescriptorArray::ClearTransitions() {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00002007 WRITE_FIELD(this, kTransitionsOffset, Smi::FromInt(0));
2008}
2009
2010
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002011void DescriptorArray::set_transitions(TransitionArray* transitions_array,
2012 WriteBarrierMode mode) {
2013 Heap* heap = GetHeap();
2014 WRITE_FIELD(this, kTransitionsOffset, transitions_array);
2015 CONDITIONAL_WRITE_BARRIER(
2016 heap, this, kTransitionsOffset, transitions_array, mode);
2017}
2018
2019
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002020Object** DescriptorArray::GetKeySlot(int descriptor_number) {
2021 ASSERT(descriptor_number < number_of_descriptors());
2022 return HeapObject::RawField(
2023 reinterpret_cast<HeapObject*>(this),
2024 OffsetOfElementAt(ToKeyIndex(descriptor_number)));
2025}
2026
2027
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002028String* DescriptorArray::GetKey(int descriptor_number) {
2029 ASSERT(descriptor_number < number_of_descriptors());
2030 return String::cast(get(ToKeyIndex(descriptor_number)));
2031}
2032
2033
verwaest@chromium.org37141392012-05-31 13:27:02 +00002034Object** DescriptorArray::GetValueSlot(int descriptor_number) {
2035 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002036 return HeapObject::RawField(
2037 reinterpret_cast<HeapObject*>(this),
2038 OffsetOfElementAt(ToValueIndex(descriptor_number)));
verwaest@chromium.org37141392012-05-31 13:27:02 +00002039}
2040
2041
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002042Object* DescriptorArray::GetValue(int descriptor_number) {
2043 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002044 return get(ToValueIndex(descriptor_number));
2045}
2046
2047
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002048PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002049 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002050 Object* details = get(ToDetailsIndex(descriptor_number));
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002051 return PropertyDetails(Smi::cast(details));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002052}
2053
2054
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002055PropertyType DescriptorArray::GetType(int descriptor_number) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002056 return GetDetails(descriptor_number).type();
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002057}
2058
2059
2060int DescriptorArray::GetFieldIndex(int descriptor_number) {
2061 return Descriptor::IndexFromValue(GetValue(descriptor_number));
2062}
2063
2064
2065JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
2066 return JSFunction::cast(GetValue(descriptor_number));
2067}
2068
2069
2070Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
2071 ASSERT(GetType(descriptor_number) == CALLBACKS);
2072 return GetValue(descriptor_number);
2073}
2074
2075
2076AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
2077 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002078 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002079 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002080}
2081
2082
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002083void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2084 desc->Init(GetKey(descriptor_number),
2085 GetValue(descriptor_number),
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002086 GetDetails(descriptor_number));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002087}
2088
2089
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002090void DescriptorArray::Set(int descriptor_number,
2091 Descriptor* desc,
2092 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002093 // Range check.
2094 ASSERT(descriptor_number < number_of_descriptors());
2095
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002096 NoIncrementalWriteBarrierSet(this,
2097 ToKeyIndex(descriptor_number),
2098 desc->GetKey());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002099 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002100 ToValueIndex(descriptor_number),
2101 desc->GetValue());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002102 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002103 ToDetailsIndex(descriptor_number),
2104 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002105}
2106
2107
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002108void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2109 int first, int second) {
2110 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002111 NoIncrementalWriteBarrierSwap(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002112 ToValueIndex(first),
2113 ToValueIndex(second));
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002114 NoIncrementalWriteBarrierSwap(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002115 ToDetailsIndex(first),
2116 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002117}
2118
2119
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002120FixedArray::WhitenessWitness::WhitenessWitness(FixedArray* array)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002121 : marking_(array->GetHeap()->incremental_marking()) {
2122 marking_->EnterNoMarkingScope();
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002123 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002124}
2125
2126
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002127FixedArray::WhitenessWitness::~WhitenessWitness() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002128 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002129}
2130
2131
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002132template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002133int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2134 const int kMinCapacity = 32;
2135 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2136 if (capacity < kMinCapacity) {
2137 capacity = kMinCapacity; // Guarantee min capacity.
2138 }
2139 return capacity;
2140}
2141
2142
2143template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002144int HashTable<Shape, Key>::FindEntry(Key key) {
2145 return FindEntry(GetIsolate(), key);
2146}
2147
2148
2149// Find entry for key otherwise return kNotFound.
2150template<typename Shape, typename Key>
2151int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2152 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002153 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002154 uint32_t count = 1;
2155 // EnsureCapacity will guarantee the hash table is never full.
2156 while (true) {
2157 Object* element = KeyAt(entry);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002158 // Empty entry.
2159 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2160 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002161 Shape::IsMatch(key, element)) return entry;
2162 entry = NextProbe(entry, count++, capacity);
2163 }
2164 return kNotFound;
2165}
2166
2167
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002168bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002169 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002170 if (!max_index_object->IsSmi()) return false;
2171 return 0 !=
2172 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2173}
2174
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002175uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002176 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002177 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002178 if (!max_index_object->IsSmi()) return 0;
2179 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2180 return value >> kRequiresSlowElementsTagSize;
2181}
2182
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002183void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002184 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002185}
2186
2187
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002188// ------------------------------------
2189// Cast operations
2190
2191
2192CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002193CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002194CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002195CAST_ACCESSOR(DeoptimizationInputData)
2196CAST_ACCESSOR(DeoptimizationOutputData)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002197CAST_ACCESSOR(TypeFeedbackCells)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002198CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002199CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002200CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002201CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002202CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002203CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002204CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002205CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002206CAST_ACCESSOR(String)
2207CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002208CAST_ACCESSOR(SeqAsciiString)
2209CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002210CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002211CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002212CAST_ACCESSOR(ExternalString)
2213CAST_ACCESSOR(ExternalAsciiString)
2214CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002215CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002216CAST_ACCESSOR(JSObject)
2217CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002218CAST_ACCESSOR(HeapObject)
2219CAST_ACCESSOR(HeapNumber)
2220CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002221CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002222CAST_ACCESSOR(SharedFunctionInfo)
2223CAST_ACCESSOR(Map)
2224CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002225CAST_ACCESSOR(GlobalObject)
2226CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002227CAST_ACCESSOR(JSGlobalObject)
2228CAST_ACCESSOR(JSBuiltinsObject)
2229CAST_ACCESSOR(Code)
2230CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002231CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002232CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002233CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002234CAST_ACCESSOR(JSSet)
2235CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002236CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002237CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002238CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002239CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002240CAST_ACCESSOR(ExternalArray)
2241CAST_ACCESSOR(ExternalByteArray)
2242CAST_ACCESSOR(ExternalUnsignedByteArray)
2243CAST_ACCESSOR(ExternalShortArray)
2244CAST_ACCESSOR(ExternalUnsignedShortArray)
2245CAST_ACCESSOR(ExternalIntArray)
2246CAST_ACCESSOR(ExternalUnsignedIntArray)
2247CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002248CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002249CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002250CAST_ACCESSOR(Struct)
2251
2252
2253#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2254 STRUCT_LIST(MAKE_STRUCT_CAST)
2255#undef MAKE_STRUCT_CAST
2256
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002257
2258template <typename Shape, typename Key>
2259HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002260 ASSERT(obj->IsHashTable());
2261 return reinterpret_cast<HashTable*>(obj);
2262}
2263
2264
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002265SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002266SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002267
ager@chromium.orgac091b72010-05-05 07:34:42 +00002268SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002269
2270
2271uint32_t String::hash_field() {
2272 return READ_UINT32_FIELD(this, kHashFieldOffset);
2273}
2274
2275
2276void String::set_hash_field(uint32_t value) {
2277 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002278#if V8_HOST_ARCH_64_BIT
2279 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2280#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002281}
2282
2283
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002284bool String::Equals(String* other) {
2285 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002286 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2287 return false;
2288 }
2289 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002290}
2291
2292
lrn@chromium.org303ada72010-10-27 09:33:13 +00002293MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002294 if (!StringShape(this).IsCons()) return this;
2295 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002296 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002297 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002298}
2299
2300
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002301String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002302 MaybeObject* flat = TryFlatten(pretenure);
2303 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002304 if (!flat->ToObject(&successfully_flattened)) return this;
2305 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002306}
2307
2308
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002309uint16_t String::Get(int index) {
2310 ASSERT(index >= 0 && index < length());
2311 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002312 case kSeqStringTag | kAsciiStringTag:
2313 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2314 case kSeqStringTag | kTwoByteStringTag:
2315 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2316 case kConsStringTag | kAsciiStringTag:
2317 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002318 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002319 case kExternalStringTag | kAsciiStringTag:
2320 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2321 case kExternalStringTag | kTwoByteStringTag:
2322 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002323 case kSlicedStringTag | kAsciiStringTag:
2324 case kSlicedStringTag | kTwoByteStringTag:
2325 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002326 default:
2327 break;
2328 }
2329
2330 UNREACHABLE();
2331 return 0;
2332}
2333
2334
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002335void String::Set(int index, uint16_t value) {
2336 ASSERT(index >= 0 && index < length());
2337 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002338
ager@chromium.org5ec48922009-05-05 07:25:34 +00002339 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002340 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2341 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002342}
2343
2344
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002345bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002346 if (!StringShape(this).IsCons()) return true;
2347 return ConsString::cast(this)->second()->length() == 0;
2348}
2349
2350
2351String* String::GetUnderlying() {
2352 // Giving direct access to underlying string only makes sense if the
2353 // wrapping string is already flattened.
2354 ASSERT(this->IsFlat());
2355 ASSERT(StringShape(this).IsIndirect());
2356 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2357 const int kUnderlyingOffset = SlicedString::kParentOffset;
2358 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002359}
2360
2361
ager@chromium.org7c537e22008-10-16 08:43:32 +00002362uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002363 ASSERT(index >= 0 && index < length());
2364 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2365}
2366
2367
ager@chromium.org7c537e22008-10-16 08:43:32 +00002368void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002369 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2370 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2371 static_cast<byte>(value));
2372}
2373
2374
ager@chromium.org7c537e22008-10-16 08:43:32 +00002375Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002376 return FIELD_ADDR(this, kHeaderSize);
2377}
2378
2379
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002380char* SeqAsciiString::GetChars() {
2381 return reinterpret_cast<char*>(GetCharsAddress());
2382}
2383
2384
ager@chromium.org7c537e22008-10-16 08:43:32 +00002385Address SeqTwoByteString::GetCharsAddress() {
2386 return FIELD_ADDR(this, kHeaderSize);
2387}
2388
2389
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002390uc16* SeqTwoByteString::GetChars() {
2391 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2392}
2393
2394
ager@chromium.org7c537e22008-10-16 08:43:32 +00002395uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002396 ASSERT(index >= 0 && index < length());
2397 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2398}
2399
2400
ager@chromium.org7c537e22008-10-16 08:43:32 +00002401void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002402 ASSERT(index >= 0 && index < length());
2403 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2404}
2405
2406
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002407int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002408 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002409}
2410
2411
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002412int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002413 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002414}
2415
2416
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002417String* SlicedString::parent() {
2418 return String::cast(READ_FIELD(this, kParentOffset));
2419}
2420
2421
2422void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002423 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002424 WRITE_FIELD(this, kParentOffset, parent);
2425}
2426
2427
2428SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2429
2430
ager@chromium.org870a0b62008-11-04 11:43:05 +00002431String* ConsString::first() {
2432 return String::cast(READ_FIELD(this, kFirstOffset));
2433}
2434
2435
2436Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002437 return READ_FIELD(this, kFirstOffset);
2438}
2439
2440
ager@chromium.org870a0b62008-11-04 11:43:05 +00002441void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002442 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002443 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002444}
2445
2446
ager@chromium.org870a0b62008-11-04 11:43:05 +00002447String* ConsString::second() {
2448 return String::cast(READ_FIELD(this, kSecondOffset));
2449}
2450
2451
2452Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002453 return READ_FIELD(this, kSecondOffset);
2454}
2455
2456
ager@chromium.org870a0b62008-11-04 11:43:05 +00002457void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002458 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002459 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002460}
2461
2462
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002463bool ExternalString::is_short() {
2464 InstanceType type = map()->instance_type();
2465 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002466}
2467
2468
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002469const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002470 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2471}
2472
2473
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002474void ExternalAsciiString::update_data_cache() {
2475 if (is_short()) return;
2476 const char** data_field =
2477 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2478 *data_field = resource()->data();
2479}
2480
2481
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002482void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002483 const ExternalAsciiString::Resource* resource) {
2484 *reinterpret_cast<const Resource**>(
2485 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002486 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002487}
2488
2489
2490const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002491 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002492}
2493
2494
2495uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2496 ASSERT(index >= 0 && index < length());
2497 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002498}
2499
2500
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002501const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002502 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2503}
2504
2505
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002506void ExternalTwoByteString::update_data_cache() {
2507 if (is_short()) return;
2508 const uint16_t** data_field =
2509 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2510 *data_field = resource()->data();
2511}
2512
2513
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002514void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002515 const ExternalTwoByteString::Resource* resource) {
2516 *reinterpret_cast<const Resource**>(
2517 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002518 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002519}
2520
2521
2522const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002523 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002524}
2525
2526
2527uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2528 ASSERT(index >= 0 && index < length());
2529 return GetChars()[index];
2530}
2531
2532
2533const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2534 unsigned start) {
2535 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002536}
2537
2538
ager@chromium.orgac091b72010-05-05 07:34:42 +00002539void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002540 set_finger_index(kEntriesIndex);
2541 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002542}
2543
2544
2545void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002546 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002547 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002548 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002549 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002550 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002551 MakeZeroSize();
2552}
2553
2554
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002555int JSFunctionResultCache::size() {
2556 return Smi::cast(get(kCacheSizeIndex))->value();
2557}
2558
2559
2560void JSFunctionResultCache::set_size(int size) {
2561 set(kCacheSizeIndex, Smi::FromInt(size));
2562}
2563
2564
2565int JSFunctionResultCache::finger_index() {
2566 return Smi::cast(get(kFingerIndex))->value();
2567}
2568
2569
2570void JSFunctionResultCache::set_finger_index(int finger_index) {
2571 set(kFingerIndex, Smi::FromInt(finger_index));
2572}
2573
2574
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002575byte ByteArray::get(int index) {
2576 ASSERT(index >= 0 && index < this->length());
2577 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2578}
2579
2580
2581void ByteArray::set(int index, byte value) {
2582 ASSERT(index >= 0 && index < this->length());
2583 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2584}
2585
2586
2587int ByteArray::get_int(int index) {
2588 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2589 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2590}
2591
2592
2593ByteArray* ByteArray::FromDataStartAddress(Address address) {
2594 ASSERT_TAG_ALIGNED(address);
2595 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2596}
2597
2598
2599Address ByteArray::GetDataStartAddress() {
2600 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2601}
2602
2603
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002604uint8_t* ExternalPixelArray::external_pixel_pointer() {
2605 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002606}
2607
2608
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002609uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002610 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002611 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002612 return ptr[index];
2613}
2614
2615
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002616MaybeObject* ExternalPixelArray::get(int index) {
2617 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2618}
2619
2620
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002621void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002622 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002623 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002624 ptr[index] = value;
2625}
2626
2627
ager@chromium.org3811b432009-10-28 14:53:37 +00002628void* ExternalArray::external_pointer() {
2629 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2630 return reinterpret_cast<void*>(ptr);
2631}
2632
2633
2634void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2635 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2636 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2637}
2638
2639
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002640int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002641 ASSERT((index >= 0) && (index < this->length()));
2642 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2643 return ptr[index];
2644}
2645
2646
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002647MaybeObject* ExternalByteArray::get(int index) {
2648 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2649}
2650
2651
ager@chromium.org3811b432009-10-28 14:53:37 +00002652void ExternalByteArray::set(int index, int8_t value) {
2653 ASSERT((index >= 0) && (index < this->length()));
2654 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2655 ptr[index] = value;
2656}
2657
2658
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002659uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002660 ASSERT((index >= 0) && (index < this->length()));
2661 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2662 return ptr[index];
2663}
2664
2665
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002666MaybeObject* ExternalUnsignedByteArray::get(int index) {
2667 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2668}
2669
2670
ager@chromium.org3811b432009-10-28 14:53:37 +00002671void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2672 ASSERT((index >= 0) && (index < this->length()));
2673 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2674 ptr[index] = value;
2675}
2676
2677
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002678int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002679 ASSERT((index >= 0) && (index < this->length()));
2680 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2681 return ptr[index];
2682}
2683
2684
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002685MaybeObject* ExternalShortArray::get(int index) {
2686 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2687}
2688
2689
ager@chromium.org3811b432009-10-28 14:53:37 +00002690void ExternalShortArray::set(int index, int16_t value) {
2691 ASSERT((index >= 0) && (index < this->length()));
2692 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2693 ptr[index] = value;
2694}
2695
2696
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002697uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002698 ASSERT((index >= 0) && (index < this->length()));
2699 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2700 return ptr[index];
2701}
2702
2703
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002704MaybeObject* ExternalUnsignedShortArray::get(int index) {
2705 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2706}
2707
2708
ager@chromium.org3811b432009-10-28 14:53:37 +00002709void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2710 ASSERT((index >= 0) && (index < this->length()));
2711 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2712 ptr[index] = value;
2713}
2714
2715
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002716int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002717 ASSERT((index >= 0) && (index < this->length()));
2718 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2719 return ptr[index];
2720}
2721
2722
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002723MaybeObject* ExternalIntArray::get(int index) {
2724 return GetHeap()->NumberFromInt32(get_scalar(index));
2725}
2726
2727
ager@chromium.org3811b432009-10-28 14:53:37 +00002728void ExternalIntArray::set(int index, int32_t value) {
2729 ASSERT((index >= 0) && (index < this->length()));
2730 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2731 ptr[index] = value;
2732}
2733
2734
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002735uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002736 ASSERT((index >= 0) && (index < this->length()));
2737 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2738 return ptr[index];
2739}
2740
2741
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002742MaybeObject* ExternalUnsignedIntArray::get(int index) {
2743 return GetHeap()->NumberFromUint32(get_scalar(index));
2744}
2745
2746
ager@chromium.org3811b432009-10-28 14:53:37 +00002747void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2748 ASSERT((index >= 0) && (index < this->length()));
2749 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2750 ptr[index] = value;
2751}
2752
2753
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002754float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002755 ASSERT((index >= 0) && (index < this->length()));
2756 float* ptr = static_cast<float*>(external_pointer());
2757 return ptr[index];
2758}
2759
2760
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002761MaybeObject* ExternalFloatArray::get(int index) {
2762 return GetHeap()->NumberFromDouble(get_scalar(index));
2763}
2764
2765
ager@chromium.org3811b432009-10-28 14:53:37 +00002766void ExternalFloatArray::set(int index, float value) {
2767 ASSERT((index >= 0) && (index < this->length()));
2768 float* ptr = static_cast<float*>(external_pointer());
2769 ptr[index] = value;
2770}
2771
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002772
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002773double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002774 ASSERT((index >= 0) && (index < this->length()));
2775 double* ptr = static_cast<double*>(external_pointer());
2776 return ptr[index];
2777}
2778
2779
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002780MaybeObject* ExternalDoubleArray::get(int index) {
2781 return GetHeap()->NumberFromDouble(get_scalar(index));
2782}
2783
2784
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002785void ExternalDoubleArray::set(int index, double value) {
2786 ASSERT((index >= 0) && (index < this->length()));
2787 double* ptr = static_cast<double*>(external_pointer());
2788 ptr[index] = value;
2789}
2790
2791
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002792int Map::visitor_id() {
2793 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2794}
2795
2796
2797void Map::set_visitor_id(int id) {
2798 ASSERT(0 <= id && id < 256);
2799 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2800}
2801
ager@chromium.org3811b432009-10-28 14:53:37 +00002802
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002803int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002804 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2805}
2806
2807
2808int Map::inobject_properties() {
2809 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002810}
2811
2812
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002813int Map::pre_allocated_property_fields() {
2814 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2815}
2816
2817
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002818int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002819 int instance_size = map->instance_size();
2820 if (instance_size != kVariableSizeSentinel) return instance_size;
2821 // We can ignore the "symbol" bit becase it is only set for symbols
2822 // and implies a string type.
2823 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002824 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002825 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002826 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002827 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002828 if (instance_type == ASCII_STRING_TYPE) {
2829 return SeqAsciiString::SizeFor(
2830 reinterpret_cast<SeqAsciiString*>(this)->length());
2831 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002832 if (instance_type == BYTE_ARRAY_TYPE) {
2833 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2834 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002835 if (instance_type == FREE_SPACE_TYPE) {
2836 return reinterpret_cast<FreeSpace*>(this)->size();
2837 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002838 if (instance_type == STRING_TYPE) {
2839 return SeqTwoByteString::SizeFor(
2840 reinterpret_cast<SeqTwoByteString*>(this)->length());
2841 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002842 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2843 return FixedDoubleArray::SizeFor(
2844 reinterpret_cast<FixedDoubleArray*>(this)->length());
2845 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002846 ASSERT(instance_type == CODE_TYPE);
2847 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002848}
2849
2850
2851void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002852 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002853 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002854 ASSERT(0 <= value && value < 256);
2855 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2856}
2857
2858
ager@chromium.org7c537e22008-10-16 08:43:32 +00002859void Map::set_inobject_properties(int value) {
2860 ASSERT(0 <= value && value < 256);
2861 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2862}
2863
2864
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002865void Map::set_pre_allocated_property_fields(int value) {
2866 ASSERT(0 <= value && value < 256);
2867 WRITE_BYTE_FIELD(this,
2868 kPreAllocatedPropertyFieldsOffset,
2869 static_cast<byte>(value));
2870}
2871
2872
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002873InstanceType Map::instance_type() {
2874 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2875}
2876
2877
2878void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002879 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2880}
2881
2882
2883int Map::unused_property_fields() {
2884 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2885}
2886
2887
2888void Map::set_unused_property_fields(int value) {
2889 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2890}
2891
2892
2893byte Map::bit_field() {
2894 return READ_BYTE_FIELD(this, kBitFieldOffset);
2895}
2896
2897
2898void Map::set_bit_field(byte value) {
2899 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2900}
2901
2902
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002903byte Map::bit_field2() {
2904 return READ_BYTE_FIELD(this, kBitField2Offset);
2905}
2906
2907
2908void Map::set_bit_field2(byte value) {
2909 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2910}
2911
2912
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002913void Map::set_non_instance_prototype(bool value) {
2914 if (value) {
2915 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2916 } else {
2917 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2918 }
2919}
2920
2921
2922bool Map::has_non_instance_prototype() {
2923 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2924}
2925
2926
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002927void Map::set_function_with_prototype(bool value) {
2928 if (value) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002929 set_bit_field3(bit_field3() | (1 << kFunctionWithPrototype));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002930 } else {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002931 set_bit_field3(bit_field3() & ~(1 << kFunctionWithPrototype));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002932 }
2933}
2934
2935
2936bool Map::function_with_prototype() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002937 return ((1 << kFunctionWithPrototype) & bit_field3()) != 0;
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002938}
2939
2940
ager@chromium.org870a0b62008-11-04 11:43:05 +00002941void Map::set_is_access_check_needed(bool access_check_needed) {
2942 if (access_check_needed) {
2943 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2944 } else {
2945 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2946 }
2947}
2948
2949
2950bool Map::is_access_check_needed() {
2951 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2952}
2953
2954
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002955void Map::set_is_extensible(bool value) {
2956 if (value) {
2957 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2958 } else {
2959 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2960 }
2961}
2962
2963bool Map::is_extensible() {
2964 return ((1 << kIsExtensible) & bit_field2()) != 0;
2965}
2966
2967
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002968void Map::set_attached_to_shared_function_info(bool value) {
2969 if (value) {
2970 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2971 } else {
2972 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2973 }
2974}
2975
2976bool Map::attached_to_shared_function_info() {
2977 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2978}
2979
2980
2981void Map::set_is_shared(bool value) {
2982 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002983 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002984 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002985 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002986 }
2987}
2988
2989bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002990 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002991}
2992
2993
2994JSFunction* Map::unchecked_constructor() {
2995 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2996}
2997
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002998
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002999Code::Flags Code::flags() {
3000 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
3001}
3002
3003
3004void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003005 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003006 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003007 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
3008 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003009 ExtractArgumentsCountFromFlags(flags) >= 0);
3010 WRITE_INT_FIELD(this, kFlagsOffset, flags);
3011}
3012
3013
3014Code::Kind Code::kind() {
3015 return ExtractKindFromFlags(flags());
3016}
3017
3018
kasper.lund7276f142008-07-30 08:49:36 +00003019InlineCacheState Code::ic_state() {
3020 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003021 // Only allow uninitialized or debugger states for non-IC code
3022 // objects. This is used in the debugger to determine whether or not
3023 // a call to code object has been replaced with a debug break call.
3024 ASSERT(is_inline_cache_stub() ||
3025 result == UNINITIALIZED ||
3026 result == DEBUG_BREAK ||
3027 result == DEBUG_PREPARE_STEP_IN);
3028 return result;
3029}
3030
3031
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003032Code::ExtraICState Code::extra_ic_state() {
3033 ASSERT(is_inline_cache_stub());
3034 return ExtractExtraICStateFromFlags(flags());
3035}
3036
3037
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003038Code::StubType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003039 return ExtractTypeFromFlags(flags());
3040}
3041
3042
3043int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003044 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003045 return ExtractArgumentsCountFromFlags(flags());
3046}
3047
3048
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003049int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003050 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003051 kind() == UNARY_OP_IC ||
3052 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003053 kind() == COMPARE_IC ||
3054 kind() == TO_BOOLEAN_IC);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003055 return StubMajorKeyField::decode(
3056 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasper.lund7276f142008-07-30 08:49:36 +00003057}
3058
3059
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003060void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003061 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003062 kind() == UNARY_OP_IC ||
3063 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003064 kind() == COMPARE_IC ||
3065 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00003066 ASSERT(0 <= major && major < 256);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003067 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3068 int updated = StubMajorKeyField::update(previous, major);
3069 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003070}
3071
3072
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003073bool Code::is_pregenerated() {
3074 return kind() == STUB && IsPregeneratedField::decode(flags());
3075}
3076
3077
3078void Code::set_is_pregenerated(bool value) {
3079 ASSERT(kind() == STUB);
3080 Flags f = flags();
3081 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3082 set_flags(f);
3083}
3084
3085
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003086bool Code::optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003087 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003088 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3089}
3090
3091
3092void Code::set_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003093 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003094 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3095}
3096
3097
3098bool Code::has_deoptimization_support() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003099 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003100 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3101 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003102}
3103
3104
3105void Code::set_has_deoptimization_support(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003106 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003107 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3108 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3109 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3110}
3111
3112
3113bool Code::has_debug_break_slots() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003114 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003115 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3116 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3117}
3118
3119
3120void Code::set_has_debug_break_slots(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003121 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003122 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3123 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3124 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003125}
3126
3127
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003128bool Code::is_compiled_optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003129 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003130 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3131 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3132}
3133
3134
3135void Code::set_compiled_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003136 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003137 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3138 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3139 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3140}
3141
3142
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003143int Code::allow_osr_at_loop_nesting_level() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003144 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003145 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3146}
3147
3148
3149void Code::set_allow_osr_at_loop_nesting_level(int level) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003150 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003151 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3152 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3153}
3154
3155
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003156int Code::profiler_ticks() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003157 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003158 return READ_BYTE_FIELD(this, kProfilerTicksOffset);
3159}
3160
3161
3162void Code::set_profiler_ticks(int ticks) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003163 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003164 ASSERT(ticks < 256);
3165 WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
3166}
3167
3168
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003169unsigned Code::stack_slots() {
3170 ASSERT(kind() == OPTIMIZED_FUNCTION);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003171 return StackSlotsField::decode(
3172 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003173}
3174
3175
3176void Code::set_stack_slots(unsigned slots) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003177 CHECK(slots <= (1 << kStackSlotsBitCount));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003178 ASSERT(kind() == OPTIMIZED_FUNCTION);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003179 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3180 int updated = StackSlotsField::update(previous, slots);
3181 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003182}
3183
3184
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003185unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003186 ASSERT(kind() == OPTIMIZED_FUNCTION);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003187 return SafepointTableOffsetField::decode(
3188 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003189}
3190
3191
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003192void Code::set_safepoint_table_offset(unsigned offset) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003193 CHECK(offset <= (1 << kSafepointTableOffsetBitCount));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003194 ASSERT(kind() == OPTIMIZED_FUNCTION);
3195 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003196 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3197 int updated = SafepointTableOffsetField::update(previous, offset);
3198 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003199}
3200
3201
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003202unsigned Code::stack_check_table_offset() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003203 ASSERT_EQ(FUNCTION, kind());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003204 return StackCheckTableOffsetField::decode(
3205 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003206}
3207
3208
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003209void Code::set_stack_check_table_offset(unsigned offset) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003210 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003211 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003212 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3213 int updated = StackCheckTableOffsetField::update(previous, offset);
3214 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003215}
3216
3217
3218CheckType Code::check_type() {
3219 ASSERT(is_call_stub() || is_keyed_call_stub());
3220 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3221 return static_cast<CheckType>(type);
3222}
3223
3224
3225void Code::set_check_type(CheckType value) {
3226 ASSERT(is_call_stub() || is_keyed_call_stub());
3227 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3228}
3229
3230
danno@chromium.org40cb8782011-05-25 07:58:50 +00003231byte Code::unary_op_type() {
3232 ASSERT(is_unary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003233 return UnaryOpTypeField::decode(
3234 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003235}
3236
3237
danno@chromium.org40cb8782011-05-25 07:58:50 +00003238void Code::set_unary_op_type(byte value) {
3239 ASSERT(is_unary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003240 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3241 int updated = UnaryOpTypeField::update(previous, value);
3242 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003243}
3244
3245
danno@chromium.org40cb8782011-05-25 07:58:50 +00003246byte Code::binary_op_type() {
3247 ASSERT(is_binary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003248 return BinaryOpTypeField::decode(
3249 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003250}
3251
3252
danno@chromium.org40cb8782011-05-25 07:58:50 +00003253void Code::set_binary_op_type(byte value) {
3254 ASSERT(is_binary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003255 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3256 int updated = BinaryOpTypeField::update(previous, value);
3257 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003258}
3259
3260
danno@chromium.org40cb8782011-05-25 07:58:50 +00003261byte Code::binary_op_result_type() {
3262 ASSERT(is_binary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003263 return BinaryOpResultTypeField::decode(
3264 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003265}
3266
3267
danno@chromium.org40cb8782011-05-25 07:58:50 +00003268void Code::set_binary_op_result_type(byte value) {
3269 ASSERT(is_binary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003270 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3271 int updated = BinaryOpResultTypeField::update(previous, value);
3272 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003273}
3274
3275
3276byte Code::compare_state() {
3277 ASSERT(is_compare_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003278 return CompareStateField::decode(
3279 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003280}
3281
3282
3283void Code::set_compare_state(byte value) {
3284 ASSERT(is_compare_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003285 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3286 int updated = CompareStateField::update(previous, value);
3287 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003288}
3289
3290
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003291byte Code::compare_operation() {
3292 ASSERT(is_compare_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003293 return CompareOperationField::decode(
3294 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003295}
3296
3297
3298void Code::set_compare_operation(byte value) {
3299 ASSERT(is_compare_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003300 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3301 int updated = CompareOperationField::update(previous, value);
3302 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003303}
3304
3305
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003306byte Code::to_boolean_state() {
3307 ASSERT(is_to_boolean_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003308 return ToBooleanStateField::decode(
3309 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003310}
3311
3312
3313void Code::set_to_boolean_state(byte value) {
3314 ASSERT(is_to_boolean_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003315 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3316 int updated = ToBooleanStateField::update(previous, value);
3317 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003318}
3319
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003320
3321bool Code::has_function_cache() {
3322 ASSERT(kind() == STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003323 return HasFunctionCacheField::decode(
3324 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003325}
3326
3327
3328void Code::set_has_function_cache(bool flag) {
3329 ASSERT(kind() == STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003330 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3331 int updated = HasFunctionCacheField::update(previous, flag);
3332 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003333}
3334
3335
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003336bool Code::is_inline_cache_stub() {
3337 Kind kind = this->kind();
3338 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3339}
3340
3341
3342Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003343 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003344 ExtraICState extra_ic_state,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003345 StubType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003346 int argc,
3347 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003348 // Extra IC state is only allowed for call IC stubs or for store IC
3349 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003350 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003351 kind == CALL_IC ||
3352 kind == STORE_IC ||
3353 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003354 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003355 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003356 | ICStateField::encode(ic_state)
3357 | TypeField::encode(type)
3358 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003359 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003360 | CacheHolderField::encode(holder);
3361 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003362}
3363
3364
3365Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003366 StubType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003367 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003368 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003369 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003370 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003371}
3372
3373
3374Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003375 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003376}
3377
3378
kasper.lund7276f142008-07-30 08:49:36 +00003379InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003380 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003381}
3382
3383
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003384Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003385 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003386}
3387
3388
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003389Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003390 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003391}
3392
3393
3394int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003395 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003396}
3397
3398
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003399InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003400 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003401}
3402
3403
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003404Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003405 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003406 return static_cast<Flags>(bits);
3407}
3408
3409
ager@chromium.org8bb60582008-12-11 12:02:20 +00003410Code* Code::GetCodeFromTargetAddress(Address address) {
3411 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3412 // GetCodeFromTargetAddress might be called when marking objects during mark
3413 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3414 // Code::cast. Code::cast does not work when the object's map is
3415 // marked.
3416 Code* result = reinterpret_cast<Code*>(code);
3417 return result;
3418}
3419
3420
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003421Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3422 return HeapObject::
3423 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3424}
3425
3426
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003427Object* Map::prototype() {
3428 return READ_FIELD(this, kPrototypeOffset);
3429}
3430
3431
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003432void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003433 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003434 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003435 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003436}
3437
3438
danno@chromium.org40cb8782011-05-25 07:58:50 +00003439DescriptorArray* Map::instance_descriptors() {
3440 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3441 if (object->IsSmi()) {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003442 return GetHeap()->empty_descriptor_array();
danno@chromium.org40cb8782011-05-25 07:58:50 +00003443 } else {
3444 return DescriptorArray::cast(object);
3445 }
3446}
3447
3448
3449void Map::init_instance_descriptors() {
3450 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3451}
3452
3453
3454void Map::clear_instance_descriptors() {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003455 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003456 if (!object->IsSmi()) {
3457 WRITE_FIELD(
3458 this,
3459 kInstanceDescriptorsOrBitField3Offset,
3460 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3461 }
3462}
3463
3464
3465void Map::set_instance_descriptors(DescriptorArray* value,
3466 WriteBarrierMode mode) {
3467 Object* object = READ_FIELD(this,
3468 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003469 Heap* heap = GetHeap();
3470 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003471 clear_instance_descriptors();
3472 return;
3473 } else {
3474 if (object->IsSmi()) {
3475 value->set_bit_field3_storage(Smi::cast(object)->value());
3476 } else {
3477 value->set_bit_field3_storage(
3478 DescriptorArray::cast(object)->bit_field3_storage());
3479 }
3480 }
3481 ASSERT(!is_shared());
3482 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003483 CONDITIONAL_WRITE_BARRIER(
3484 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003485}
3486
3487
3488int Map::bit_field3() {
3489 Object* object = READ_FIELD(this,
3490 kInstanceDescriptorsOrBitField3Offset);
3491 if (object->IsSmi()) {
3492 return Smi::cast(object)->value();
3493 } else {
3494 return DescriptorArray::cast(object)->bit_field3_storage();
3495 }
3496}
3497
3498
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003499void Map::ClearDescriptorArray() {
3500 int bitfield3 = bit_field3();
3501#ifdef DEBUG
3502 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3503 if (!object->IsSmi()) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003504 ZapTransitions();
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003505 }
3506#endif
3507 WRITE_FIELD(this,
3508 kInstanceDescriptorsOrBitField3Offset,
3509 Smi::FromInt(bitfield3));
3510}
3511
3512
danno@chromium.org40cb8782011-05-25 07:58:50 +00003513void Map::set_bit_field3(int value) {
3514 ASSERT(Smi::IsValid(value));
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003515 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003516 if (object->IsSmi()) {
3517 WRITE_FIELD(this,
3518 kInstanceDescriptorsOrBitField3Offset,
3519 Smi::FromInt(value));
3520 } else {
3521 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3522 }
3523}
3524
3525
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003526Object* Map::GetBackPointer() {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003527 return READ_FIELD(this, kBackPointerOffset);
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003528}
3529
3530
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003531bool Map::HasElementsTransition() {
3532 return HasTransitionArray() && transitions()->HasElementsTransition();
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003533}
3534
3535
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003536bool Map::HasTransitionArray() {
3537 return instance_descriptors()->HasTransitionArray();
3538}
3539
3540
3541Map* Map::elements_transition_map() {
3542 return transitions()->elements_transition();
3543}
3544
3545
3546MaybeObject* Map::AddTransition(String* key, Object* value) {
3547 if (HasTransitionArray()) return transitions()->CopyInsert(key, value);
3548 return TransitionArray::NewWith(key, value);
3549}
3550
3551
3552// If the map does not have a descriptor array, install a new empty
3553// descriptor array that has room for a transition array.
3554static MaybeObject* AllowTransitions(Map* map) {
3555 if (map->instance_descriptors()->MayContainTransitions()) return map;
3556 DescriptorArray* descriptors;
3557 MaybeObject* maybe_descriptors =
3558 DescriptorArray::Allocate(0, DescriptorArray::CANNOT_BE_SHARED);
3559 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
3560 map->set_instance_descriptors(descriptors);
3561 return descriptors;
3562}
3563
3564
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003565// If the descriptor is using the empty transition array, install a new empty
3566// transition array that will have place for an element transition.
3567static MaybeObject* EnsureHasTransitionArray(Map* map) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003568 if (map->HasTransitionArray()) return map;
3569
3570 AllowTransitions(map);
3571
3572 TransitionArray* transitions;
3573 MaybeObject* maybe_transitions = TransitionArray::Allocate(0);
3574 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
3575 MaybeObject* added_transitions = map->set_transitions(transitions);
3576 if (added_transitions->IsFailure()) return added_transitions;
3577 return transitions;
3578}
3579
3580
3581MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003582 MaybeObject* allow_elements = EnsureHasTransitionArray(this);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003583 if (allow_elements->IsFailure()) return allow_elements;
3584 transitions()->set_elements_transition(transitioned_map);
3585 return this;
3586}
3587
3588
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003589FixedArray* Map::GetPrototypeTransitions() {
3590 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
3591 if (!transitions()->HasPrototypeTransitions()) {
3592 return GetHeap()->empty_fixed_array();
3593 }
3594 return transitions()->GetPrototypeTransitions();
3595}
3596
3597
3598MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
3599 MaybeObject* allow_prototype = EnsureHasTransitionArray(this);
3600 if (allow_prototype->IsFailure()) return allow_prototype;
3601#ifdef DEBUG
3602 if (HasPrototypeTransitions()) {
3603 ASSERT(GetPrototypeTransitions() != proto_transitions);
3604 ZapPrototypeTransitions();
3605 }
3606#endif
3607 transitions()->SetPrototypeTransitions(proto_transitions);
3608 return this;
3609}
3610
3611
3612bool Map::HasPrototypeTransitions() {
3613 return HasTransitionArray() && transitions()->HasPrototypeTransitions();
3614}
3615
3616
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003617TransitionArray* Map::transitions() {
3618 return instance_descriptors()->transitions();
3619}
3620
3621
3622void Map::ClearTransitions() {
3623#ifdef DEBUG
3624 ZapTransitions();
3625#endif
3626 DescriptorArray* descriptors = instance_descriptors();
3627 if (descriptors->number_of_descriptors() == 0) {
3628 ClearDescriptorArray();
3629 } else {
3630 descriptors->ClearTransitions();
3631 }
3632}
3633
3634
3635MaybeObject* Map::set_transitions(TransitionArray* transitions_array) {
3636 MaybeObject* allow_transitions = AllowTransitions(this);
3637 if (allow_transitions->IsFailure()) return allow_transitions;
3638#ifdef DEBUG
3639 if (HasTransitionArray()) {
3640 ASSERT(transitions() != transitions_array);
3641 ZapTransitions();
3642 }
3643#endif
3644 instance_descriptors()->set_transitions(transitions_array);
3645 return this;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003646}
3647
3648
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003649void Map::init_back_pointer(Object* undefined) {
3650 ASSERT(undefined->IsUndefined());
3651 WRITE_FIELD(this, kBackPointerOffset, undefined);
3652}
3653
3654
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003655void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
3656 Heap* heap = GetHeap();
3657 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
3658 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
3659 (value->IsMap() && GetBackPointer()->IsUndefined()));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003660 WRITE_FIELD(this, kBackPointerOffset, value);
3661 CONDITIONAL_WRITE_BARRIER(heap, this, kBackPointerOffset, value, mode);
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003662}
3663
3664
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003665// Can either be Smi (no transitions), normal transition array, or a transition
3666// array with the header overwritten as a Smi (thus iterating).
3667TransitionArray* Map::unchecked_transition_array() {
3668 ASSERT(HasTransitionArray());
3669 Object* object = *HeapObject::RawField(instance_descriptors(),
3670 DescriptorArray::kTransitionsOffset);
3671 ASSERT(!object->IsSmi());
3672 TransitionArray* transition_array = static_cast<TransitionArray*>(object);
3673 return transition_array;
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003674}
3675
3676
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003677HeapObject* Map::UncheckedPrototypeTransitions() {
3678 ASSERT(HasTransitionArray());
3679 ASSERT(unchecked_transition_array()->HasPrototypeTransitions());
3680 return unchecked_transition_array()->UncheckedPrototypeTransitions();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003681}
3682
3683
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003684ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003685ACCESSORS(Map, constructor, Object, kConstructorOffset)
3686
3687ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003688ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003689ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003690
3691ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3692ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003693ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003694
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003695ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003696
3697ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3698ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3699ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3700ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003701ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003702ACCESSORS(AccessorInfo, expected_receiver_type, Object,
3703 kExpectedReceiverTypeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003704
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003705ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3706ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3707
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003708ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3709ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3710ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3711
3712ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3713ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3714ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3715ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3716ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3717ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3718
3719ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3720ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3721
3722ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3723ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3724
3725ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3726ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003727ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3728 kPropertyAccessorsOffset)
3729ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3730 kPrototypeTemplateOffset)
3731ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3732ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3733 kNamedPropertyHandlerOffset)
3734ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3735 kIndexedPropertyHandlerOffset)
3736ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3737 kInstanceTemplateOffset)
3738ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3739ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003740ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3741 kInstanceCallHandlerOffset)
3742ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3743 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003744ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003745
3746ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003747ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3748 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003749
3750ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3751ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3752
3753ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3754
3755ACCESSORS(Script, source, Object, kSourceOffset)
3756ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003757ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003758ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
3759ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003760ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003761ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003762ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003763ACCESSORS_TO_SMI(Script, type, kTypeOffset)
3764ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
3765ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003766ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003767ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003768ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
3769 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003770
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003771#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003772ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3773ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3774ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3775ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3776
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003777ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
3778ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
3779ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003780ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003781#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003782
3783ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003784ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
3785 kOptimizedCodeMapOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003786ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3787ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003788ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3789 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003790ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003791ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3792ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003793ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003794ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3795 kThisPropertyAssignmentsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003796SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003797
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00003798
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003799BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3800 kHiddenPrototypeBit)
3801BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3802BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3803 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003804BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3805 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003806BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3807 kIsExpressionBit)
3808BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3809 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003810BOOL_GETTER(SharedFunctionInfo,
3811 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003812 has_only_simple_this_property_assignments,
3813 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003814BOOL_ACCESSORS(SharedFunctionInfo,
3815 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003816 allows_lazy_compilation,
3817 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003818BOOL_ACCESSORS(SharedFunctionInfo,
3819 compiler_hints,
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003820 allows_lazy_compilation_without_context,
3821 kAllowLazyCompilationWithoutContext)
3822BOOL_ACCESSORS(SharedFunctionInfo,
3823 compiler_hints,
whesse@chromium.org7b260152011-06-20 15:33:18 +00003824 uses_arguments,
3825 kUsesArguments)
3826BOOL_ACCESSORS(SharedFunctionInfo,
3827 compiler_hints,
3828 has_duplicate_parameters,
3829 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003830
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003831
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003832#if V8_HOST_ARCH_32_BIT
3833SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3834SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003835 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003836SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003837 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003838SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3839SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003840 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003841SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3842SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003843 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003844SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003845 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003846SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003847 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003848SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003849SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
3850SMI_ACCESSORS(SharedFunctionInfo,
3851 stress_deopt_counter,
3852 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003853#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003854
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003855#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003856 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003857 int holder::name() { \
3858 int value = READ_INT_FIELD(this, offset); \
3859 ASSERT(kHeapObjectTag == 1); \
3860 ASSERT((value & kHeapObjectTag) == 0); \
3861 return value >> 1; \
3862 } \
3863 void holder::set_##name(int value) { \
3864 ASSERT(kHeapObjectTag == 1); \
3865 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3866 (value & 0xC0000000) == 0x000000000); \
3867 WRITE_INT_FIELD(this, \
3868 offset, \
3869 (value << 1) & ~kHeapObjectTag); \
3870 }
3871
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003872#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3873 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003874 INT_ACCESSORS(holder, name, offset)
3875
3876
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003877PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003878PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3879 formal_parameter_count,
3880 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003881
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003882PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3883 expected_nof_properties,
3884 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003885PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3886
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003887PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3888PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3889 start_position_and_type,
3890 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003891
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003892PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3893 function_token_position,
3894 kFunctionTokenPositionOffset)
3895PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3896 compiler_hints,
3897 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003898
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003899PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3900 this_property_assignments_count,
3901 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003902PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003903
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003904PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, counters, kCountersOffset)
3905PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3906 stress_deopt_counter,
3907 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003908#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003909
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003910
3911int SharedFunctionInfo::construction_count() {
3912 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3913}
3914
3915
3916void SharedFunctionInfo::set_construction_count(int value) {
3917 ASSERT(0 <= value && value < 256);
3918 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3919}
3920
3921
whesse@chromium.org7b260152011-06-20 15:33:18 +00003922BOOL_ACCESSORS(SharedFunctionInfo,
3923 compiler_hints,
3924 live_objects_may_exist,
3925 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003926
3927
3928bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003929 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003930}
3931
3932
whesse@chromium.org7b260152011-06-20 15:33:18 +00003933BOOL_GETTER(SharedFunctionInfo,
3934 compiler_hints,
3935 optimization_disabled,
3936 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003937
3938
3939void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3940 set_compiler_hints(BooleanBit::set(compiler_hints(),
3941 kOptimizationDisabled,
3942 disable));
3943 // If disabling optimizations we reflect that in the code object so
3944 // it will not be counted as optimizable code.
3945 if ((code()->kind() == Code::FUNCTION) && disable) {
3946 code()->set_optimizable(false);
3947 }
3948}
3949
3950
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003951int SharedFunctionInfo::profiler_ticks() {
3952 if (code()->kind() != Code::FUNCTION) return 0;
3953 return code()->profiler_ticks();
3954}
3955
3956
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003957LanguageMode SharedFunctionInfo::language_mode() {
3958 int hints = compiler_hints();
3959 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3960 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3961 return EXTENDED_MODE;
3962 }
3963 return BooleanBit::get(hints, kStrictModeFunction)
3964 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003965}
3966
3967
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003968void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3969 // We only allow language mode transitions that go set the same language mode
3970 // again or go up in the chain:
3971 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3972 ASSERT(this->language_mode() == CLASSIC_MODE ||
3973 this->language_mode() == language_mode ||
3974 language_mode == EXTENDED_MODE);
3975 int hints = compiler_hints();
3976 hints = BooleanBit::set(
3977 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3978 hints = BooleanBit::set(
3979 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3980 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003981}
3982
3983
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003984bool SharedFunctionInfo::is_classic_mode() {
3985 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3986}
3987
3988BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3989 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003990BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3991BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3992 name_should_print_as_anonymous,
3993 kNameShouldPrintAsAnonymous)
3994BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3995BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00003996BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
3997BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
3998 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003999BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004000BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_cache, kDontCache)
whesse@chromium.org7b260152011-06-20 15:33:18 +00004001
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004002void SharedFunctionInfo::BeforeVisitingPointers() {
4003 if (IsInobjectSlackTrackingInProgress()) DetachInitialMap();
4004
4005 // Flush optimized code map on major GC.
4006 // Note: we may experiment with rebuilding it or retaining entries
4007 // which should survive as we iterate through optimized functions
4008 // anyway.
4009 set_optimized_code_map(Smi::FromInt(0));
4010}
4011
4012
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004013ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
4014ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
4015
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00004016ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
4017
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00004018bool Script::HasValidSource() {
4019 Object* src = this->source();
4020 if (!src->IsString()) return true;
4021 String* src_str = String::cast(src);
4022 if (!StringShape(src_str).IsExternal()) return true;
4023 if (src_str->IsAsciiRepresentation()) {
4024 return ExternalAsciiString::cast(src)->resource() != NULL;
4025 } else if (src_str->IsTwoByteRepresentation()) {
4026 return ExternalTwoByteString::cast(src)->resource() != NULL;
4027 }
4028 return true;
4029}
4030
4031
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00004032void SharedFunctionInfo::DontAdaptArguments() {
4033 ASSERT(code()->kind() == Code::BUILTIN);
4034 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
4035}
4036
4037
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004038int SharedFunctionInfo::start_position() {
4039 return start_position_and_type() >> kStartPositionShift;
4040}
4041
4042
4043void SharedFunctionInfo::set_start_position(int start_position) {
4044 set_start_position_and_type((start_position << kStartPositionShift)
4045 | (start_position_and_type() & ~kStartPositionMask));
4046}
4047
4048
4049Code* SharedFunctionInfo::code() {
4050 return Code::cast(READ_FIELD(this, kCodeOffset));
4051}
4052
4053
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004054Code* SharedFunctionInfo::unchecked_code() {
4055 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
4056}
4057
4058
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004059void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004060 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004061 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004062}
4063
4064
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004065ScopeInfo* SharedFunctionInfo::scope_info() {
4066 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00004067}
4068
4069
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004070void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00004071 WriteBarrierMode mode) {
4072 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004073 CONDITIONAL_WRITE_BARRIER(GetHeap(),
4074 this,
4075 kScopeInfoOffset,
4076 reinterpret_cast<Object*>(value),
4077 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00004078}
4079
4080
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004081bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004082 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004083 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004084}
4085
4086
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004087bool SharedFunctionInfo::IsApiFunction() {
4088 return function_data()->IsFunctionTemplateInfo();
4089}
4090
4091
4092FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
4093 ASSERT(IsApiFunction());
4094 return FunctionTemplateInfo::cast(function_data());
4095}
4096
4097
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004098bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00004099 return function_data()->IsSmi();
4100}
4101
4102
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004103BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
4104 ASSERT(HasBuiltinFunctionId());
4105 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004106}
4107
4108
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004109int SharedFunctionInfo::code_age() {
4110 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
4111}
4112
4113
4114void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00004115 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
4116 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004117}
4118
4119
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004120int SharedFunctionInfo::ic_age() {
4121 return ICAgeBits::decode(counters());
4122}
4123
4124
4125void SharedFunctionInfo::set_ic_age(int ic_age) {
4126 set_counters(ICAgeBits::update(counters(), ic_age));
4127}
4128
4129
4130int SharedFunctionInfo::deopt_count() {
4131 return DeoptCountBits::decode(counters());
4132}
4133
4134
4135void SharedFunctionInfo::set_deopt_count(int deopt_count) {
4136 set_counters(DeoptCountBits::update(counters(), deopt_count));
4137}
4138
4139
4140void SharedFunctionInfo::increment_deopt_count() {
4141 int value = counters();
4142 int deopt_count = DeoptCountBits::decode(value);
4143 deopt_count = (deopt_count + 1) & DeoptCountBits::kMax;
4144 set_counters(DeoptCountBits::update(value, deopt_count));
4145}
4146
4147
4148int SharedFunctionInfo::opt_reenable_tries() {
4149 return OptReenableTriesBits::decode(counters());
4150}
4151
4152
4153void SharedFunctionInfo::set_opt_reenable_tries(int tries) {
4154 set_counters(OptReenableTriesBits::update(counters(), tries));
4155}
4156
4157
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004158bool SharedFunctionInfo::has_deoptimization_support() {
4159 Code* code = this->code();
4160 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
4161}
4162
4163
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004164void SharedFunctionInfo::TryReenableOptimization() {
4165 int tries = opt_reenable_tries();
4166 set_opt_reenable_tries((tries + 1) & OptReenableTriesBits::kMax);
4167 // We reenable optimization whenever the number of tries is a large
4168 // enough power of 2.
4169 if (tries >= 16 && (((tries - 1) & tries) == 0)) {
4170 set_optimization_disabled(false);
4171 set_opt_count(0);
4172 set_deopt_count(0);
4173 code()->set_optimizable(true);
4174 }
4175}
4176
4177
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004178bool JSFunction::IsBuiltin() {
4179 return context()->global()->IsJSBuiltinsObject();
4180}
4181
4182
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004183bool JSFunction::NeedsArgumentsAdaption() {
4184 return shared()->formal_parameter_count() !=
4185 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
4186}
4187
4188
4189bool JSFunction::IsOptimized() {
4190 return code()->kind() == Code::OPTIMIZED_FUNCTION;
4191}
4192
4193
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00004194bool JSFunction::IsOptimizable() {
4195 return code()->kind() == Code::FUNCTION && code()->optimizable();
4196}
4197
4198
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004199bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004200 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004201}
4202
4203
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004204Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004205 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004206}
4207
4208
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004209Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004210 return reinterpret_cast<Code*>(
4211 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004212}
4213
4214
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004215void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004216 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004217 Address entry = value->entry();
4218 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004219 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
4220 this,
4221 HeapObject::RawField(this, kCodeEntryOffset),
4222 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004223}
4224
4225
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004226void JSFunction::ReplaceCode(Code* code) {
4227 bool was_optimized = IsOptimized();
4228 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
4229
4230 set_code(code);
4231
4232 // Add/remove the function from the list of optimized functions for this
4233 // context based on the state change.
4234 if (!was_optimized && is_optimized) {
4235 context()->global_context()->AddOptimizedFunction(this);
4236 }
4237 if (was_optimized && !is_optimized) {
4238 context()->global_context()->RemoveOptimizedFunction(this);
4239 }
4240}
4241
4242
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004243Context* JSFunction::context() {
4244 return Context::cast(READ_FIELD(this, kContextOffset));
4245}
4246
4247
4248Object* JSFunction::unchecked_context() {
4249 return READ_FIELD(this, kContextOffset);
4250}
4251
4252
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004253SharedFunctionInfo* JSFunction::unchecked_shared() {
4254 return reinterpret_cast<SharedFunctionInfo*>(
4255 READ_FIELD(this, kSharedFunctionInfoOffset));
4256}
4257
4258
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004259void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004260 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004261 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004262 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004263}
4264
4265ACCESSORS(JSFunction, prototype_or_initial_map, Object,
4266 kPrototypeOrInitialMapOffset)
4267
4268
4269Map* JSFunction::initial_map() {
4270 return Map::cast(prototype_or_initial_map());
4271}
4272
4273
4274void JSFunction::set_initial_map(Map* value) {
4275 set_prototype_or_initial_map(value);
4276}
4277
4278
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004279MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
4280 Map* initial_map) {
4281 Context* global_context = context()->global_context();
4282 Object* array_function =
4283 global_context->get(Context::ARRAY_FUNCTION_INDEX);
4284 if (array_function->IsJSFunction() &&
4285 this == JSFunction::cast(array_function)) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004286 // Replace all of the cached initial array maps in the global context with
4287 // the appropriate transitioned elements kind maps.
4288 Heap* heap = GetHeap();
4289 MaybeObject* maybe_maps =
4290 heap->AllocateFixedArrayWithHoles(kElementsKindCount);
4291 FixedArray* maps;
4292 if (!maybe_maps->To(&maps)) return maybe_maps;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004293
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004294 Map* current_map = initial_map;
4295 ElementsKind kind = current_map->elements_kind();
4296 ASSERT(kind == GetInitialFastElementsKind());
4297 maps->set(kind, current_map);
4298 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
4299 i < kFastElementsKindCount; ++i) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004300 Map* new_map;
4301 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
4302 MaybeObject* maybe_new_map =
4303 current_map->CreateNextElementsTransition(next_kind);
4304 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
4305 maps->set(next_kind, new_map);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004306 current_map = new_map;
4307 }
4308 global_context->set_js_array_maps(maps);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004309 }
4310 set_initial_map(initial_map);
4311 return this;
4312}
4313
4314
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004315bool JSFunction::has_initial_map() {
4316 return prototype_or_initial_map()->IsMap();
4317}
4318
4319
4320bool JSFunction::has_instance_prototype() {
4321 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4322}
4323
4324
4325bool JSFunction::has_prototype() {
4326 return map()->has_non_instance_prototype() || has_instance_prototype();
4327}
4328
4329
4330Object* JSFunction::instance_prototype() {
4331 ASSERT(has_instance_prototype());
4332 if (has_initial_map()) return initial_map()->prototype();
4333 // When there is no initial map and the prototype is a JSObject, the
4334 // initial map field is used for the prototype field.
4335 return prototype_or_initial_map();
4336}
4337
4338
4339Object* JSFunction::prototype() {
4340 ASSERT(has_prototype());
4341 // If the function's prototype property has been set to a non-JSObject
4342 // value, that value is stored in the constructor field of the map.
4343 if (map()->has_non_instance_prototype()) return map()->constructor();
4344 return instance_prototype();
4345}
4346
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004347
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00004348bool JSFunction::should_have_prototype() {
4349 return map()->function_with_prototype();
4350}
4351
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004352
4353bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004354 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004355}
4356
4357
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004358FixedArray* JSFunction::literals() {
4359 ASSERT(!shared()->bound());
4360 return literals_or_bindings();
4361}
4362
4363
4364void JSFunction::set_literals(FixedArray* literals) {
4365 ASSERT(!shared()->bound());
4366 set_literals_or_bindings(literals);
4367}
4368
4369
4370FixedArray* JSFunction::function_bindings() {
4371 ASSERT(shared()->bound());
4372 return literals_or_bindings();
4373}
4374
4375
4376void JSFunction::set_function_bindings(FixedArray* bindings) {
4377 ASSERT(shared()->bound());
4378 // Bound function literal may be initialized to the empty fixed array
4379 // before the bindings are set.
4380 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4381 bindings->map() == GetHeap()->fixed_cow_array_map());
4382 set_literals_or_bindings(bindings);
4383}
4384
4385
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004386int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004387 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004388 return literals()->length();
4389}
4390
4391
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004392Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004393 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004394 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004395}
4396
4397
4398void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4399 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004400 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004401 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004402 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004403}
4404
4405
4406Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004407 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004408 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4409}
4410
4411
4412void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4413 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004414 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004415 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004416 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004417}
4418
4419
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004420ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004421ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004422ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4423ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4424
4425
4426void JSProxy::InitializeBody(int object_size, Object* value) {
4427 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4428 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4429 WRITE_FIELD(this, offset, value);
4430 }
4431}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004432
4433
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004434ACCESSORS(JSSet, table, Object, kTableOffset)
4435ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004436ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4437ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004438
4439
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004440Address Foreign::foreign_address() {
4441 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004442}
4443
4444
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004445void Foreign::set_foreign_address(Address value) {
4446 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004447}
4448
4449
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004450ACCESSORS(JSModule, context, Object, kContextOffset)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004451ACCESSORS(JSModule, scope_info, ScopeInfo, kScopeInfoOffset)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004452
4453
4454JSModule* JSModule::cast(Object* obj) {
4455 ASSERT(obj->IsJSModule());
4456 ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
4457 return reinterpret_cast<JSModule*>(obj);
4458}
4459
4460
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004461ACCESSORS(JSValue, value, Object, kValueOffset)
4462
4463
4464JSValue* JSValue::cast(Object* obj) {
4465 ASSERT(obj->IsJSValue());
4466 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4467 return reinterpret_cast<JSValue*>(obj);
4468}
4469
4470
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004471ACCESSORS(JSDate, value, Object, kValueOffset)
4472ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4473ACCESSORS(JSDate, year, Object, kYearOffset)
4474ACCESSORS(JSDate, month, Object, kMonthOffset)
4475ACCESSORS(JSDate, day, Object, kDayOffset)
4476ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4477ACCESSORS(JSDate, hour, Object, kHourOffset)
4478ACCESSORS(JSDate, min, Object, kMinOffset)
4479ACCESSORS(JSDate, sec, Object, kSecOffset)
4480
4481
4482JSDate* JSDate::cast(Object* obj) {
4483 ASSERT(obj->IsJSDate());
4484 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4485 return reinterpret_cast<JSDate*>(obj);
4486}
4487
4488
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004489ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4490ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4491ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4492ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4493ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4494SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4495SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4496
4497
4498JSMessageObject* JSMessageObject::cast(Object* obj) {
4499 ASSERT(obj->IsJSMessageObject());
4500 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4501 return reinterpret_cast<JSMessageObject*>(obj);
4502}
4503
4504
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004505INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004506ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004507ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004508ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004509ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004510ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00004511INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004512
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004513byte* Code::instruction_start() {
4514 return FIELD_ADDR(this, kHeaderSize);
4515}
4516
4517
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004518byte* Code::instruction_end() {
4519 return instruction_start() + instruction_size();
4520}
4521
4522
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004523int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004524 return RoundUp(instruction_size(), kObjectAlignment);
4525}
4526
4527
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004528FixedArray* Code::unchecked_deoptimization_data() {
4529 return reinterpret_cast<FixedArray*>(
4530 READ_FIELD(this, kDeoptimizationDataOffset));
4531}
4532
4533
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004534ByteArray* Code::unchecked_relocation_info() {
4535 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004536}
4537
4538
4539byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004540 return unchecked_relocation_info()->GetDataStartAddress();
4541}
4542
4543
4544int Code::relocation_size() {
4545 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004546}
4547
4548
4549byte* Code::entry() {
4550 return instruction_start();
4551}
4552
4553
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004554bool Code::contains(byte* inner_pointer) {
4555 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004556}
4557
4558
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004559ACCESSORS(JSArray, length, Object, kLengthOffset)
4560
4561
ager@chromium.org236ad962008-09-25 09:45:57 +00004562ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004563
4564
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004565JSRegExp::Type JSRegExp::TypeTag() {
4566 Object* data = this->data();
4567 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4568 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4569 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004570}
4571
4572
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004573JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4574 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4575 return static_cast<JSRegExp::Type>(smi->value());
4576}
4577
4578
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004579int JSRegExp::CaptureCount() {
4580 switch (TypeTag()) {
4581 case ATOM:
4582 return 0;
4583 case IRREGEXP:
4584 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4585 default:
4586 UNREACHABLE();
4587 return -1;
4588 }
4589}
4590
4591
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004592JSRegExp::Flags JSRegExp::GetFlags() {
4593 ASSERT(this->data()->IsFixedArray());
4594 Object* data = this->data();
4595 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4596 return Flags(smi->value());
4597}
4598
4599
4600String* JSRegExp::Pattern() {
4601 ASSERT(this->data()->IsFixedArray());
4602 Object* data = this->data();
4603 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4604 return pattern;
4605}
4606
4607
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004608Object* JSRegExp::DataAt(int index) {
4609 ASSERT(TypeTag() != NOT_COMPILED);
4610 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004611}
4612
4613
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004614Object* JSRegExp::DataAtUnchecked(int index) {
4615 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4616 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4617 return READ_FIELD(fa, offset);
4618}
4619
4620
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004621void JSRegExp::SetDataAt(int index, Object* value) {
4622 ASSERT(TypeTag() != NOT_COMPILED);
4623 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4624 FixedArray::cast(data())->set(index, value);
4625}
4626
4627
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004628void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4629 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4630 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4631 if (value->IsSmi()) {
4632 fa->set_unchecked(index, Smi::cast(value));
4633 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004634 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004635 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4636 }
4637}
4638
4639
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004640ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004641 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004642#if DEBUG
4643 FixedArrayBase* fixed_array =
4644 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4645 Map* map = fixed_array->map();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004646 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
4647 (map == GetHeap()->fixed_array_map() ||
4648 map == GetHeap()->fixed_cow_array_map())) ||
4649 (IsFastDoubleElementsKind(kind) &&
4650 (fixed_array->IsFixedDoubleArray() ||
4651 fixed_array == GetHeap()->empty_fixed_array())) ||
4652 (kind == DICTIONARY_ELEMENTS &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004653 fixed_array->IsFixedArray() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004654 fixed_array->IsDictionary()) ||
4655 (kind > DICTIONARY_ELEMENTS));
4656 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4657 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004658#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004659 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004660}
4661
4662
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004663ElementsAccessor* JSObject::GetElementsAccessor() {
4664 return ElementsAccessor::ForKind(GetElementsKind());
4665}
4666
4667
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004668bool JSObject::HasFastObjectElements() {
4669 return IsFastObjectElementsKind(GetElementsKind());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004670}
4671
4672
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004673bool JSObject::HasFastSmiElements() {
4674 return IsFastSmiElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004675}
4676
4677
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004678bool JSObject::HasFastSmiOrObjectElements() {
4679 return IsFastSmiOrObjectElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004680}
4681
4682
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004683bool JSObject::HasFastDoubleElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004684 return IsFastDoubleElementsKind(GetElementsKind());
4685}
4686
4687
4688bool JSObject::HasFastHoleyElements() {
4689 return IsFastHoleyElementsKind(GetElementsKind());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004690}
4691
4692
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004693bool JSObject::HasDictionaryElements() {
4694 return GetElementsKind() == DICTIONARY_ELEMENTS;
4695}
4696
4697
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004698bool JSObject::HasNonStrictArgumentsElements() {
4699 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4700}
4701
4702
ager@chromium.org3811b432009-10-28 14:53:37 +00004703bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004704 HeapObject* array = elements();
4705 ASSERT(array != NULL);
4706 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004707}
4708
4709
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004710#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4711bool JSObject::HasExternal##name##Elements() { \
4712 HeapObject* array = elements(); \
4713 ASSERT(array != NULL); \
4714 if (!array->IsHeapObject()) \
4715 return false; \
4716 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004717}
4718
4719
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004720EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4721EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4722EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4723EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4724 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4725EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4726EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4727 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4728EXTERNAL_ELEMENTS_CHECK(Float,
4729 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004730EXTERNAL_ELEMENTS_CHECK(Double,
4731 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004732EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004733
4734
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004735bool JSObject::HasNamedInterceptor() {
4736 return map()->has_named_interceptor();
4737}
4738
4739
4740bool JSObject::HasIndexedInterceptor() {
4741 return map()->has_indexed_interceptor();
4742}
4743
4744
lrn@chromium.org303ada72010-10-27 09:33:13 +00004745MaybeObject* JSObject::EnsureWritableFastElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004746 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004747 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004748 Isolate* isolate = GetIsolate();
4749 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004750 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004751 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4752 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004753 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4754 return maybe_writable_elems;
4755 }
4756 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004757 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004758 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004759 return writable_elems;
4760}
4761
4762
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004763StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004764 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004765 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004766}
4767
4768
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004769SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004770 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004771 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004772}
4773
4774
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004775bool String::IsHashFieldComputed(uint32_t field) {
4776 return (field & kHashNotComputedMask) == 0;
4777}
4778
4779
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004780bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004781 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004782}
4783
4784
4785uint32_t String::Hash() {
4786 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004787 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004788 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004789 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004790 return ComputeAndSetHash();
4791}
4792
4793
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004794StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004795 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004796 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004797 array_index_(0),
4798 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4799 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004800 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004801 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004802}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004803
4804
4805bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004806 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004807}
4808
4809
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004810void StringHasher::AddCharacter(uint32_t c) {
4811 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4812 AddSurrogatePair(c); // Not inlined.
4813 return;
4814 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004815 // Use the Jenkins one-at-a-time hash function to update the hash
4816 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004817 raw_running_hash_ += c;
4818 raw_running_hash_ += (raw_running_hash_ << 10);
4819 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004820 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004821 if (is_array_index_) {
4822 if (c < '0' || c > '9') {
4823 is_array_index_ = false;
4824 } else {
4825 int d = c - '0';
4826 if (is_first_char_) {
4827 is_first_char_ = false;
4828 if (c == '0' && length_ > 1) {
4829 is_array_index_ = false;
4830 return;
4831 }
4832 }
4833 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4834 is_array_index_ = false;
4835 } else {
4836 array_index_ = array_index_ * 10 + d;
4837 }
4838 }
4839 }
4840}
4841
4842
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004843void StringHasher::AddCharacterNoIndex(uint32_t c) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00004844 ASSERT(!is_array_index());
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004845 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4846 AddSurrogatePairNoIndex(c); // Not inlined.
4847 return;
4848 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004849 raw_running_hash_ += c;
4850 raw_running_hash_ += (raw_running_hash_ << 10);
4851 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4852}
4853
4854
4855uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004856 // Get the calculated raw hash value and do some more bit ops to distribute
4857 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004858 uint32_t result = raw_running_hash_;
4859 result += (result << 3);
4860 result ^= (result >> 11);
4861 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004862 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004863 result = 27;
4864 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004865 return result;
4866}
4867
4868
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004869template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004870uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4871 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004872 if (!hasher.has_trivial_hash()) {
4873 int i;
4874 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4875 hasher.AddCharacter(chars[i]);
4876 }
4877 for (; i < length; i++) {
4878 hasher.AddCharacterNoIndex(chars[i]);
4879 }
4880 }
4881 return hasher.GetHashField();
4882}
4883
4884
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004885bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004886 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004887 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4888 return false;
4889 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004890 return SlowAsArrayIndex(index);
4891}
4892
4893
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004894Object* JSReceiver::GetPrototype() {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004895 return map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004896}
4897
4898
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00004899Object* JSReceiver::GetConstructor() {
4900 return map()->constructor();
4901}
4902
4903
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004904bool JSReceiver::HasProperty(String* name) {
4905 if (IsJSProxy()) {
4906 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4907 }
4908 return GetPropertyAttribute(name) != ABSENT;
4909}
4910
4911
4912bool JSReceiver::HasLocalProperty(String* name) {
4913 if (IsJSProxy()) {
4914 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4915 }
4916 return GetLocalPropertyAttribute(name) != ABSENT;
4917}
4918
4919
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004920PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004921 return GetPropertyAttributeWithReceiver(this, key);
4922}
4923
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004924// TODO(504): this may be useful in other places too where JSGlobalProxy
4925// is used.
4926Object* JSObject::BypassGlobalProxy() {
4927 if (IsJSGlobalProxy()) {
4928 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004929 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004930 ASSERT(proto->IsJSGlobalObject());
4931 return proto;
4932 }
4933 return this;
4934}
4935
4936
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004937MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4938 return IsJSProxy()
4939 ? JSProxy::cast(this)->GetIdentityHash(flag)
4940 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004941}
4942
4943
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004944bool JSReceiver::HasElement(uint32_t index) {
4945 if (IsJSProxy()) {
4946 return JSProxy::cast(this)->HasElementWithHandler(index);
4947 }
4948 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004949}
4950
4951
4952bool AccessorInfo::all_can_read() {
4953 return BooleanBit::get(flag(), kAllCanReadBit);
4954}
4955
4956
4957void AccessorInfo::set_all_can_read(bool value) {
4958 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4959}
4960
4961
4962bool AccessorInfo::all_can_write() {
4963 return BooleanBit::get(flag(), kAllCanWriteBit);
4964}
4965
4966
4967void AccessorInfo::set_all_can_write(bool value) {
4968 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4969}
4970
4971
ager@chromium.org870a0b62008-11-04 11:43:05 +00004972bool AccessorInfo::prohibits_overwriting() {
4973 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4974}
4975
4976
4977void AccessorInfo::set_prohibits_overwriting(bool value) {
4978 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4979}
4980
4981
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004982PropertyAttributes AccessorInfo::property_attributes() {
4983 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4984}
4985
4986
4987void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004988 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004989}
4990
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004991
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004992bool AccessorInfo::IsCompatibleReceiver(Object* receiver) {
4993 Object* function_template = expected_receiver_type();
4994 if (!function_template->IsFunctionTemplateInfo()) return true;
4995 return receiver->IsInstanceOf(FunctionTemplateInfo::cast(function_template));
4996}
4997
4998
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004999template<typename Shape, typename Key>
5000void Dictionary<Shape, Key>::SetEntry(int entry,
5001 Object* key,
5002 Object* value) {
5003 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
5004}
5005
5006
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005007template<typename Shape, typename Key>
5008void Dictionary<Shape, Key>::SetEntry(int entry,
5009 Object* key,
5010 Object* value,
5011 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00005012 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005013 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005014 AssertNoAllocation no_gc;
5015 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005016 FixedArray::set(index, key, mode);
5017 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005018 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005019}
5020
5021
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005022bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
5023 ASSERT(other->IsNumber());
5024 return key == static_cast<uint32_t>(other->Number());
5025}
5026
5027
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005028uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
5029 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005030}
5031
5032
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005033uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
5034 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005035 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005036 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005037}
5038
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005039uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
5040 return ComputeIntegerHash(key, seed);
5041}
5042
5043uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
5044 uint32_t seed,
5045 Object* other) {
5046 ASSERT(other->IsNumber());
5047 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
5048}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005049
5050MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
5051 return Isolate::Current()->heap()->NumberFromUint32(key);
5052}
5053
5054
5055bool StringDictionaryShape::IsMatch(String* key, Object* other) {
5056 // We know that all entries in a hash table had their hash keys created.
5057 // Use that knowledge to have fast failure.
5058 if (key->Hash() != String::cast(other)->Hash()) return false;
5059 return key->Equals(String::cast(other));
5060}
5061
5062
5063uint32_t StringDictionaryShape::Hash(String* key) {
5064 return key->Hash();
5065}
5066
5067
5068uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
5069 return String::cast(other)->Hash();
5070}
5071
5072
5073MaybeObject* StringDictionaryShape::AsObject(String* key) {
5074 return key;
5075}
5076
5077
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005078template <int entrysize>
5079bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
5080 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005081}
5082
5083
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005084template <int entrysize>
5085uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005086 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
5087 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005088}
5089
5090
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005091template <int entrysize>
5092uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
5093 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005094 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
5095 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005096}
5097
5098
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005099template <int entrysize>
5100MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005101 return key;
5102}
5103
5104
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005105void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005106 // No write barrier is needed since empty_fixed_array is not in new space.
5107 // Please note this function is used during marking:
5108 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00005109 // - IncrementalMarking::Step
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005110 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
5111 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005112}
5113
5114
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005115void JSArray::EnsureSize(int required_size) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005116 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005117 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005118 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
5119 if (elts->length() < required_size) {
5120 // Doubling in size would be overkill, but leave some slack to avoid
5121 // constantly growing.
5122 Expand(required_size + (required_size >> 3));
5123 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005124 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005125 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
5126 // Expand will allocate a new backing store in new space even if the size
5127 // we asked for isn't larger than what we had before.
5128 Expand(required_size);
5129 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005130}
5131
5132
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005133void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005134 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005135 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
5136}
5137
5138
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005139bool JSArray::AllowsSetElementsLength() {
5140 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
5141 ASSERT(result == !HasExternalArrayElements());
5142 return result;
5143}
5144
5145
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005146MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
5147 MaybeObject* maybe_result = EnsureCanContainElements(
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005148 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005149 if (maybe_result->IsFailure()) return maybe_result;
5150 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005151 IsFastDoubleElementsKind(GetElementsKind())) ||
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005152 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005153 (IsFastObjectElementsKind(GetElementsKind()) ||
5154 (IsFastSmiElementsKind(GetElementsKind()) &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005155 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00005156 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005157 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005158 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005159}
5160
5161
lrn@chromium.org303ada72010-10-27 09:33:13 +00005162MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005163 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005164 return GetHeap()->CopyFixedArray(this);
5165}
5166
5167
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005168MaybeObject* FixedDoubleArray::Copy() {
5169 if (length() == 0) return this;
5170 return GetHeap()->CopyFixedDoubleArray(this);
5171}
5172
5173
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005174void TypeFeedbackCells::SetAstId(int index, Smi* id) {
5175 set(1 + index * 2, id);
5176}
5177
5178
5179Smi* TypeFeedbackCells::AstId(int index) {
5180 return Smi::cast(get(1 + index * 2));
5181}
5182
5183
5184void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
5185 set(index * 2, cell);
5186}
5187
5188
5189JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
5190 return JSGlobalPropertyCell::cast(get(index * 2));
5191}
5192
5193
5194Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
5195 return isolate->factory()->the_hole_value();
5196}
5197
5198
5199Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
5200 return isolate->factory()->undefined_value();
5201}
5202
5203
5204Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
5205 return heap->raw_unchecked_the_hole_value();
5206}
5207
5208
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005209SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00005210SMI_ACCESSORS(TypeFeedbackInfo, ic_with_type_info_count,
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005211 kIcWithTypeinfoCountOffset)
5212ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
5213 kTypeFeedbackCellsOffset)
5214
5215
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00005216SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
5217
5218
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005219Relocatable::Relocatable(Isolate* isolate) {
5220 ASSERT(isolate == Isolate::Current());
5221 isolate_ = isolate;
5222 prev_ = isolate->relocatable_top();
5223 isolate->set_relocatable_top(this);
5224}
5225
5226
5227Relocatable::~Relocatable() {
5228 ASSERT(isolate_ == Isolate::Current());
5229 ASSERT_EQ(isolate_->relocatable_top(), this);
5230 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005231}
5232
5233
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005234int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
5235 return map->instance_size();
5236}
5237
5238
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005239void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005240 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005241 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005242}
5243
5244
5245template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005246void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005247 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005248 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005249}
5250
5251
5252void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
5253 typedef v8::String::ExternalAsciiStringResource Resource;
5254 v->VisitExternalAsciiString(
5255 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5256}
5257
5258
5259template<typename StaticVisitor>
5260void ExternalAsciiString::ExternalAsciiStringIterateBody() {
5261 typedef v8::String::ExternalAsciiStringResource Resource;
5262 StaticVisitor::VisitExternalAsciiString(
5263 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5264}
5265
5266
5267void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
5268 typedef v8::String::ExternalStringResource Resource;
5269 v->VisitExternalTwoByteString(
5270 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5271}
5272
5273
5274template<typename StaticVisitor>
5275void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
5276 typedef v8::String::ExternalStringResource Resource;
5277 StaticVisitor::VisitExternalTwoByteString(
5278 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5279}
5280
5281#define SLOT_ADDR(obj, offset) \
5282 reinterpret_cast<Object**>((obj)->address() + offset)
5283
5284template<int start_offset, int end_offset, int size>
5285void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
5286 HeapObject* obj,
5287 ObjectVisitor* v) {
5288 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
5289}
5290
5291
5292template<int start_offset>
5293void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
5294 int object_size,
5295 ObjectVisitor* v) {
5296 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
5297}
5298
5299#undef SLOT_ADDR
5300
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005301#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005302#undef CAST_ACCESSOR
5303#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005304#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005305#undef ACCESSORS_TO_SMI
5306#undef SMI_ACCESSORS
5307#undef BOOL_GETTER
5308#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005309#undef FIELD_ADDR
5310#undef READ_FIELD
5311#undef WRITE_FIELD
5312#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005313#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005314#undef READ_DOUBLE_FIELD
5315#undef WRITE_DOUBLE_FIELD
5316#undef READ_INT_FIELD
5317#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005318#undef READ_INTPTR_FIELD
5319#undef WRITE_INTPTR_FIELD
5320#undef READ_UINT32_FIELD
5321#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005322#undef READ_SHORT_FIELD
5323#undef WRITE_SHORT_FIELD
5324#undef READ_BYTE_FIELD
5325#undef WRITE_BYTE_FIELD
5326
5327
5328} } // namespace v8::internal
5329
5330#endif // V8_OBJECTS_INL_H_