blob: af5e68363d9f66e0aea70edcf38a71c862f753f9 [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);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003055 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00003056}
3057
3058
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003059void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003060 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003061 kind() == UNARY_OP_IC ||
3062 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003063 kind() == COMPARE_IC ||
3064 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00003065 ASSERT(0 <= major && major < 256);
3066 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003067}
3068
3069
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003070bool Code::is_pregenerated() {
3071 return kind() == STUB && IsPregeneratedField::decode(flags());
3072}
3073
3074
3075void Code::set_is_pregenerated(bool value) {
3076 ASSERT(kind() == STUB);
3077 Flags f = flags();
3078 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3079 set_flags(f);
3080}
3081
3082
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003083bool Code::optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003084 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003085 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3086}
3087
3088
3089void Code::set_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003090 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003091 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3092}
3093
3094
3095bool Code::has_deoptimization_support() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003096 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003097 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3098 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003099}
3100
3101
3102void Code::set_has_deoptimization_support(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003103 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003104 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3105 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3106 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3107}
3108
3109
3110bool Code::has_debug_break_slots() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003111 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003112 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3113 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3114}
3115
3116
3117void Code::set_has_debug_break_slots(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003118 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003119 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3120 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3121 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003122}
3123
3124
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003125bool Code::is_compiled_optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003126 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003127 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3128 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3129}
3130
3131
3132void Code::set_compiled_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003133 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003134 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3135 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3136 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3137}
3138
3139
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003140int Code::allow_osr_at_loop_nesting_level() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003141 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003142 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3143}
3144
3145
3146void Code::set_allow_osr_at_loop_nesting_level(int level) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003147 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003148 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3149 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3150}
3151
3152
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003153int Code::profiler_ticks() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003154 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003155 return READ_BYTE_FIELD(this, kProfilerTicksOffset);
3156}
3157
3158
3159void Code::set_profiler_ticks(int ticks) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003160 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003161 ASSERT(ticks < 256);
3162 WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
3163}
3164
3165
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003166unsigned Code::stack_slots() {
3167 ASSERT(kind() == OPTIMIZED_FUNCTION);
3168 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3169}
3170
3171
3172void Code::set_stack_slots(unsigned slots) {
3173 ASSERT(kind() == OPTIMIZED_FUNCTION);
3174 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3175}
3176
3177
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003178unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003179 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003180 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003181}
3182
3183
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003184void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003185 ASSERT(kind() == OPTIMIZED_FUNCTION);
3186 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003187 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003188}
3189
3190
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003191unsigned Code::stack_check_table_offset() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003192 ASSERT_EQ(FUNCTION, kind());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003193 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003194}
3195
3196
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003197void Code::set_stack_check_table_offset(unsigned offset) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003198 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003199 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003200 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003201}
3202
3203
3204CheckType Code::check_type() {
3205 ASSERT(is_call_stub() || is_keyed_call_stub());
3206 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3207 return static_cast<CheckType>(type);
3208}
3209
3210
3211void Code::set_check_type(CheckType value) {
3212 ASSERT(is_call_stub() || is_keyed_call_stub());
3213 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3214}
3215
3216
danno@chromium.org40cb8782011-05-25 07:58:50 +00003217byte Code::unary_op_type() {
3218 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003219 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3220}
3221
3222
danno@chromium.org40cb8782011-05-25 07:58:50 +00003223void Code::set_unary_op_type(byte value) {
3224 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003225 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3226}
3227
3228
danno@chromium.org40cb8782011-05-25 07:58:50 +00003229byte Code::binary_op_type() {
3230 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003231 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3232}
3233
3234
danno@chromium.org40cb8782011-05-25 07:58:50 +00003235void Code::set_binary_op_type(byte value) {
3236 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003237 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3238}
3239
3240
danno@chromium.org40cb8782011-05-25 07:58:50 +00003241byte Code::binary_op_result_type() {
3242 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003243 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3244}
3245
3246
danno@chromium.org40cb8782011-05-25 07:58:50 +00003247void Code::set_binary_op_result_type(byte value) {
3248 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003249 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3250}
3251
3252
3253byte Code::compare_state() {
3254 ASSERT(is_compare_ic_stub());
3255 return READ_BYTE_FIELD(this, kCompareStateOffset);
3256}
3257
3258
3259void Code::set_compare_state(byte value) {
3260 ASSERT(is_compare_ic_stub());
3261 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3262}
3263
3264
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003265byte Code::compare_operation() {
3266 ASSERT(is_compare_ic_stub());
3267 return READ_BYTE_FIELD(this, kCompareOperationOffset);
3268}
3269
3270
3271void Code::set_compare_operation(byte value) {
3272 ASSERT(is_compare_ic_stub());
3273 WRITE_BYTE_FIELD(this, kCompareOperationOffset, value);
3274}
3275
3276
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003277byte Code::to_boolean_state() {
3278 ASSERT(is_to_boolean_ic_stub());
3279 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3280}
3281
3282
3283void Code::set_to_boolean_state(byte value) {
3284 ASSERT(is_to_boolean_ic_stub());
3285 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3286}
3287
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003288
3289bool Code::has_function_cache() {
3290 ASSERT(kind() == STUB);
3291 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3292}
3293
3294
3295void Code::set_has_function_cache(bool flag) {
3296 ASSERT(kind() == STUB);
3297 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3298}
3299
3300
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003301bool Code::is_inline_cache_stub() {
3302 Kind kind = this->kind();
3303 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3304}
3305
3306
3307Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003308 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003309 ExtraICState extra_ic_state,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003310 StubType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003311 int argc,
3312 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003313 // Extra IC state is only allowed for call IC stubs or for store IC
3314 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003315 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003316 kind == CALL_IC ||
3317 kind == STORE_IC ||
3318 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003319 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003320 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003321 | ICStateField::encode(ic_state)
3322 | TypeField::encode(type)
3323 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003324 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003325 | CacheHolderField::encode(holder);
3326 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003327}
3328
3329
3330Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003331 StubType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003332 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003333 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003334 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003335 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003336}
3337
3338
3339Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003340 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003341}
3342
3343
kasper.lund7276f142008-07-30 08:49:36 +00003344InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003345 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003346}
3347
3348
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003349Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003350 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003351}
3352
3353
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003354Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003355 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003356}
3357
3358
3359int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003360 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003361}
3362
3363
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003364InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003365 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003366}
3367
3368
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003369Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003370 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003371 return static_cast<Flags>(bits);
3372}
3373
3374
ager@chromium.org8bb60582008-12-11 12:02:20 +00003375Code* Code::GetCodeFromTargetAddress(Address address) {
3376 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3377 // GetCodeFromTargetAddress might be called when marking objects during mark
3378 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3379 // Code::cast. Code::cast does not work when the object's map is
3380 // marked.
3381 Code* result = reinterpret_cast<Code*>(code);
3382 return result;
3383}
3384
3385
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003386Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3387 return HeapObject::
3388 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3389}
3390
3391
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003392Object* Map::prototype() {
3393 return READ_FIELD(this, kPrototypeOffset);
3394}
3395
3396
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003397void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003398 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003399 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003400 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003401}
3402
3403
danno@chromium.org40cb8782011-05-25 07:58:50 +00003404DescriptorArray* Map::instance_descriptors() {
3405 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3406 if (object->IsSmi()) {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003407 return GetHeap()->empty_descriptor_array();
danno@chromium.org40cb8782011-05-25 07:58:50 +00003408 } else {
3409 return DescriptorArray::cast(object);
3410 }
3411}
3412
3413
3414void Map::init_instance_descriptors() {
3415 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3416}
3417
3418
3419void Map::clear_instance_descriptors() {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003420 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003421 if (!object->IsSmi()) {
3422 WRITE_FIELD(
3423 this,
3424 kInstanceDescriptorsOrBitField3Offset,
3425 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3426 }
3427}
3428
3429
3430void Map::set_instance_descriptors(DescriptorArray* value,
3431 WriteBarrierMode mode) {
3432 Object* object = READ_FIELD(this,
3433 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003434 Heap* heap = GetHeap();
3435 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003436 clear_instance_descriptors();
3437 return;
3438 } else {
3439 if (object->IsSmi()) {
3440 value->set_bit_field3_storage(Smi::cast(object)->value());
3441 } else {
3442 value->set_bit_field3_storage(
3443 DescriptorArray::cast(object)->bit_field3_storage());
3444 }
3445 }
3446 ASSERT(!is_shared());
3447 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003448 CONDITIONAL_WRITE_BARRIER(
3449 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003450}
3451
3452
3453int Map::bit_field3() {
3454 Object* object = READ_FIELD(this,
3455 kInstanceDescriptorsOrBitField3Offset);
3456 if (object->IsSmi()) {
3457 return Smi::cast(object)->value();
3458 } else {
3459 return DescriptorArray::cast(object)->bit_field3_storage();
3460 }
3461}
3462
3463
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003464void Map::ClearDescriptorArray() {
3465 int bitfield3 = bit_field3();
3466#ifdef DEBUG
3467 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3468 if (!object->IsSmi()) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003469 ZapTransitions();
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003470 }
3471#endif
3472 WRITE_FIELD(this,
3473 kInstanceDescriptorsOrBitField3Offset,
3474 Smi::FromInt(bitfield3));
3475}
3476
3477
danno@chromium.org40cb8782011-05-25 07:58:50 +00003478void Map::set_bit_field3(int value) {
3479 ASSERT(Smi::IsValid(value));
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003480 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003481 if (object->IsSmi()) {
3482 WRITE_FIELD(this,
3483 kInstanceDescriptorsOrBitField3Offset,
3484 Smi::FromInt(value));
3485 } else {
3486 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3487 }
3488}
3489
3490
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003491Object* Map::GetBackPointer() {
3492 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3493 if (object->IsFixedArray()) {
3494 return FixedArray::cast(object)->get(kProtoTransitionBackPointerOffset);
3495 } else {
3496 return object;
3497 }
3498}
3499
3500
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003501bool Map::HasElementsTransition() {
3502 return HasTransitionArray() && transitions()->HasElementsTransition();
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003503}
3504
3505
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003506bool Map::HasTransitionArray() {
3507 return instance_descriptors()->HasTransitionArray();
3508}
3509
3510
3511Map* Map::elements_transition_map() {
3512 return transitions()->elements_transition();
3513}
3514
3515
3516MaybeObject* Map::AddTransition(String* key, Object* value) {
3517 if (HasTransitionArray()) return transitions()->CopyInsert(key, value);
3518 return TransitionArray::NewWith(key, value);
3519}
3520
3521
3522// If the map does not have a descriptor array, install a new empty
3523// descriptor array that has room for a transition array.
3524static MaybeObject* AllowTransitions(Map* map) {
3525 if (map->instance_descriptors()->MayContainTransitions()) return map;
3526 DescriptorArray* descriptors;
3527 MaybeObject* maybe_descriptors =
3528 DescriptorArray::Allocate(0, DescriptorArray::CANNOT_BE_SHARED);
3529 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
3530 map->set_instance_descriptors(descriptors);
3531 return descriptors;
3532}
3533
3534
3535// If the descriptor does not have a transition array, install a new
3536// transition array that has room for an element transition.
3537static MaybeObject* AllowElementsTransition(Map* map) {
3538 if (map->HasTransitionArray()) return map;
3539
3540 AllowTransitions(map);
3541
3542 TransitionArray* transitions;
3543 MaybeObject* maybe_transitions = TransitionArray::Allocate(0);
3544 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
3545 MaybeObject* added_transitions = map->set_transitions(transitions);
3546 if (added_transitions->IsFailure()) return added_transitions;
3547 return transitions;
3548}
3549
3550
3551MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
3552 MaybeObject* allow_elements = AllowElementsTransition(this);
3553 if (allow_elements->IsFailure()) return allow_elements;
3554 transitions()->set_elements_transition(transitioned_map);
3555 return this;
3556}
3557
3558
3559TransitionArray* Map::transitions() {
3560 return instance_descriptors()->transitions();
3561}
3562
3563
3564void Map::ClearTransitions() {
3565#ifdef DEBUG
3566 ZapTransitions();
3567#endif
3568 DescriptorArray* descriptors = instance_descriptors();
3569 if (descriptors->number_of_descriptors() == 0) {
3570 ClearDescriptorArray();
3571 } else {
3572 descriptors->ClearTransitions();
3573 }
3574}
3575
3576
3577MaybeObject* Map::set_transitions(TransitionArray* transitions_array) {
3578 MaybeObject* allow_transitions = AllowTransitions(this);
3579 if (allow_transitions->IsFailure()) return allow_transitions;
3580#ifdef DEBUG
3581 if (HasTransitionArray()) {
3582 ASSERT(transitions() != transitions_array);
3583 ZapTransitions();
3584 }
3585#endif
3586 instance_descriptors()->set_transitions(transitions_array);
3587 return this;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003588}
3589
3590
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003591void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
3592 Heap* heap = GetHeap();
3593 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
3594 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
3595 (value->IsMap() && GetBackPointer()->IsUndefined()));
3596 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3597 if (object->IsFixedArray()) {
3598 FixedArray::cast(object)->set(
3599 kProtoTransitionBackPointerOffset, value, mode);
3600 } else {
3601 WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
3602 CONDITIONAL_WRITE_BARRIER(
3603 heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
3604 }
3605}
3606
3607
3608FixedArray* Map::prototype_transitions() {
3609 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3610 if (object->IsFixedArray()) {
3611 return FixedArray::cast(object);
3612 } else {
3613 return GetHeap()->empty_fixed_array();
3614 }
3615}
3616
3617
3618void Map::set_prototype_transitions(FixedArray* value, WriteBarrierMode mode) {
3619 Heap* heap = GetHeap();
3620 ASSERT(value != heap->empty_fixed_array());
3621 value->set(kProtoTransitionBackPointerOffset, GetBackPointer());
yangguo@chromium.org5f0b8ea2012-05-16 12:37:04 +00003622#ifdef DEBUG
3623 if (value != prototype_transitions()) {
3624 ZapPrototypeTransitions();
3625 }
3626#endif
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003627 WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
3628 CONDITIONAL_WRITE_BARRIER(
3629 heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
3630}
3631
3632
3633void Map::init_prototype_transitions(Object* undefined) {
3634 ASSERT(undefined->IsUndefined());
3635 WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, undefined);
3636}
3637
3638
3639HeapObject* Map::unchecked_prototype_transitions() {
3640 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3641 return reinterpret_cast<HeapObject*>(object);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003642}
3643
3644
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003645ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003646ACCESSORS(Map, constructor, Object, kConstructorOffset)
3647
3648ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003649ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003650ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003651
3652ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3653ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003654ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003655
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003656ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003657
3658ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3659ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3660ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3661ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003662ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003663ACCESSORS(AccessorInfo, expected_receiver_type, Object,
3664 kExpectedReceiverTypeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003665
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003666ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3667ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3668
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003669ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3670ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3671ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3672
3673ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3674ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3675ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3676ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3677ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3678ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3679
3680ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3681ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3682
3683ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3684ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3685
3686ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3687ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003688ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3689 kPropertyAccessorsOffset)
3690ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3691 kPrototypeTemplateOffset)
3692ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3693ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3694 kNamedPropertyHandlerOffset)
3695ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3696 kIndexedPropertyHandlerOffset)
3697ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3698 kInstanceTemplateOffset)
3699ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3700ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003701ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3702 kInstanceCallHandlerOffset)
3703ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3704 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003705ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003706
3707ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003708ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3709 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003710
3711ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3712ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3713
3714ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3715
3716ACCESSORS(Script, source, Object, kSourceOffset)
3717ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003718ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003719ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
3720ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003721ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003722ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003723ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003724ACCESSORS_TO_SMI(Script, type, kTypeOffset)
3725ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
3726ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003727ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003728ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003729ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
3730 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003731
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003732#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003733ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3734ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3735ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3736ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3737
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003738ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
3739ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
3740ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003741ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003742#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003743
3744ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003745ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
3746 kOptimizedCodeMapOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003747ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3748ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003749ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3750 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003751ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003752ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3753ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003754ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003755ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3756 kThisPropertyAssignmentsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003757SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003758
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00003759
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003760BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3761 kHiddenPrototypeBit)
3762BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3763BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3764 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003765BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3766 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003767BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3768 kIsExpressionBit)
3769BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3770 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003771BOOL_GETTER(SharedFunctionInfo,
3772 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003773 has_only_simple_this_property_assignments,
3774 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003775BOOL_ACCESSORS(SharedFunctionInfo,
3776 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003777 allows_lazy_compilation,
3778 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003779BOOL_ACCESSORS(SharedFunctionInfo,
3780 compiler_hints,
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003781 allows_lazy_compilation_without_context,
3782 kAllowLazyCompilationWithoutContext)
3783BOOL_ACCESSORS(SharedFunctionInfo,
3784 compiler_hints,
whesse@chromium.org7b260152011-06-20 15:33:18 +00003785 uses_arguments,
3786 kUsesArguments)
3787BOOL_ACCESSORS(SharedFunctionInfo,
3788 compiler_hints,
3789 has_duplicate_parameters,
3790 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003791
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003792
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003793#if V8_HOST_ARCH_32_BIT
3794SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3795SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003796 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003797SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003798 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003799SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3800SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003801 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003802SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3803SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003804 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003805SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003806 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003807SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003808 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003809SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003810SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
3811SMI_ACCESSORS(SharedFunctionInfo,
3812 stress_deopt_counter,
3813 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003814#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003815
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003816#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003817 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003818 int holder::name() { \
3819 int value = READ_INT_FIELD(this, offset); \
3820 ASSERT(kHeapObjectTag == 1); \
3821 ASSERT((value & kHeapObjectTag) == 0); \
3822 return value >> 1; \
3823 } \
3824 void holder::set_##name(int value) { \
3825 ASSERT(kHeapObjectTag == 1); \
3826 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3827 (value & 0xC0000000) == 0x000000000); \
3828 WRITE_INT_FIELD(this, \
3829 offset, \
3830 (value << 1) & ~kHeapObjectTag); \
3831 }
3832
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003833#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3834 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003835 INT_ACCESSORS(holder, name, offset)
3836
3837
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003838PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003839PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3840 formal_parameter_count,
3841 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003842
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003843PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3844 expected_nof_properties,
3845 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003846PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3847
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003848PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3849PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3850 start_position_and_type,
3851 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003852
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003853PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3854 function_token_position,
3855 kFunctionTokenPositionOffset)
3856PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3857 compiler_hints,
3858 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003859
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003860PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3861 this_property_assignments_count,
3862 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003863PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003864
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003865PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, counters, kCountersOffset)
3866PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3867 stress_deopt_counter,
3868 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003869#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003870
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003871
3872int SharedFunctionInfo::construction_count() {
3873 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3874}
3875
3876
3877void SharedFunctionInfo::set_construction_count(int value) {
3878 ASSERT(0 <= value && value < 256);
3879 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3880}
3881
3882
whesse@chromium.org7b260152011-06-20 15:33:18 +00003883BOOL_ACCESSORS(SharedFunctionInfo,
3884 compiler_hints,
3885 live_objects_may_exist,
3886 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003887
3888
3889bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003890 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003891}
3892
3893
whesse@chromium.org7b260152011-06-20 15:33:18 +00003894BOOL_GETTER(SharedFunctionInfo,
3895 compiler_hints,
3896 optimization_disabled,
3897 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003898
3899
3900void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3901 set_compiler_hints(BooleanBit::set(compiler_hints(),
3902 kOptimizationDisabled,
3903 disable));
3904 // If disabling optimizations we reflect that in the code object so
3905 // it will not be counted as optimizable code.
3906 if ((code()->kind() == Code::FUNCTION) && disable) {
3907 code()->set_optimizable(false);
3908 }
3909}
3910
3911
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003912int SharedFunctionInfo::profiler_ticks() {
3913 if (code()->kind() != Code::FUNCTION) return 0;
3914 return code()->profiler_ticks();
3915}
3916
3917
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003918LanguageMode SharedFunctionInfo::language_mode() {
3919 int hints = compiler_hints();
3920 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3921 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3922 return EXTENDED_MODE;
3923 }
3924 return BooleanBit::get(hints, kStrictModeFunction)
3925 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003926}
3927
3928
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003929void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3930 // We only allow language mode transitions that go set the same language mode
3931 // again or go up in the chain:
3932 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3933 ASSERT(this->language_mode() == CLASSIC_MODE ||
3934 this->language_mode() == language_mode ||
3935 language_mode == EXTENDED_MODE);
3936 int hints = compiler_hints();
3937 hints = BooleanBit::set(
3938 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3939 hints = BooleanBit::set(
3940 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3941 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003942}
3943
3944
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003945bool SharedFunctionInfo::is_classic_mode() {
3946 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3947}
3948
3949BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3950 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003951BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3952BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3953 name_should_print_as_anonymous,
3954 kNameShouldPrintAsAnonymous)
3955BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3956BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00003957BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
3958BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
3959 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003960BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003961
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003962void SharedFunctionInfo::BeforeVisitingPointers() {
3963 if (IsInobjectSlackTrackingInProgress()) DetachInitialMap();
3964
3965 // Flush optimized code map on major GC.
3966 // Note: we may experiment with rebuilding it or retaining entries
3967 // which should survive as we iterate through optimized functions
3968 // anyway.
3969 set_optimized_code_map(Smi::FromInt(0));
3970}
3971
3972
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003973ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3974ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3975
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003976ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3977
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003978bool Script::HasValidSource() {
3979 Object* src = this->source();
3980 if (!src->IsString()) return true;
3981 String* src_str = String::cast(src);
3982 if (!StringShape(src_str).IsExternal()) return true;
3983 if (src_str->IsAsciiRepresentation()) {
3984 return ExternalAsciiString::cast(src)->resource() != NULL;
3985 } else if (src_str->IsTwoByteRepresentation()) {
3986 return ExternalTwoByteString::cast(src)->resource() != NULL;
3987 }
3988 return true;
3989}
3990
3991
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003992void SharedFunctionInfo::DontAdaptArguments() {
3993 ASSERT(code()->kind() == Code::BUILTIN);
3994 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3995}
3996
3997
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003998int SharedFunctionInfo::start_position() {
3999 return start_position_and_type() >> kStartPositionShift;
4000}
4001
4002
4003void SharedFunctionInfo::set_start_position(int start_position) {
4004 set_start_position_and_type((start_position << kStartPositionShift)
4005 | (start_position_and_type() & ~kStartPositionMask));
4006}
4007
4008
4009Code* SharedFunctionInfo::code() {
4010 return Code::cast(READ_FIELD(this, kCodeOffset));
4011}
4012
4013
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004014Code* SharedFunctionInfo::unchecked_code() {
4015 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
4016}
4017
4018
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004019void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004020 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004021 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004022}
4023
4024
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004025ScopeInfo* SharedFunctionInfo::scope_info() {
4026 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00004027}
4028
4029
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004030void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00004031 WriteBarrierMode mode) {
4032 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004033 CONDITIONAL_WRITE_BARRIER(GetHeap(),
4034 this,
4035 kScopeInfoOffset,
4036 reinterpret_cast<Object*>(value),
4037 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00004038}
4039
4040
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004041bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004042 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004043 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004044}
4045
4046
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004047bool SharedFunctionInfo::IsApiFunction() {
4048 return function_data()->IsFunctionTemplateInfo();
4049}
4050
4051
4052FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
4053 ASSERT(IsApiFunction());
4054 return FunctionTemplateInfo::cast(function_data());
4055}
4056
4057
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004058bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00004059 return function_data()->IsSmi();
4060}
4061
4062
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004063BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
4064 ASSERT(HasBuiltinFunctionId());
4065 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004066}
4067
4068
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004069int SharedFunctionInfo::code_age() {
4070 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
4071}
4072
4073
4074void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00004075 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
4076 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004077}
4078
4079
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004080int SharedFunctionInfo::ic_age() {
4081 return ICAgeBits::decode(counters());
4082}
4083
4084
4085void SharedFunctionInfo::set_ic_age(int ic_age) {
4086 set_counters(ICAgeBits::update(counters(), ic_age));
4087}
4088
4089
4090int SharedFunctionInfo::deopt_count() {
4091 return DeoptCountBits::decode(counters());
4092}
4093
4094
4095void SharedFunctionInfo::set_deopt_count(int deopt_count) {
4096 set_counters(DeoptCountBits::update(counters(), deopt_count));
4097}
4098
4099
4100void SharedFunctionInfo::increment_deopt_count() {
4101 int value = counters();
4102 int deopt_count = DeoptCountBits::decode(value);
4103 deopt_count = (deopt_count + 1) & DeoptCountBits::kMax;
4104 set_counters(DeoptCountBits::update(value, deopt_count));
4105}
4106
4107
4108int SharedFunctionInfo::opt_reenable_tries() {
4109 return OptReenableTriesBits::decode(counters());
4110}
4111
4112
4113void SharedFunctionInfo::set_opt_reenable_tries(int tries) {
4114 set_counters(OptReenableTriesBits::update(counters(), tries));
4115}
4116
4117
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004118bool SharedFunctionInfo::has_deoptimization_support() {
4119 Code* code = this->code();
4120 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
4121}
4122
4123
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004124void SharedFunctionInfo::TryReenableOptimization() {
4125 int tries = opt_reenable_tries();
4126 set_opt_reenable_tries((tries + 1) & OptReenableTriesBits::kMax);
4127 // We reenable optimization whenever the number of tries is a large
4128 // enough power of 2.
4129 if (tries >= 16 && (((tries - 1) & tries) == 0)) {
4130 set_optimization_disabled(false);
4131 set_opt_count(0);
4132 set_deopt_count(0);
4133 code()->set_optimizable(true);
4134 }
4135}
4136
4137
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004138bool JSFunction::IsBuiltin() {
4139 return context()->global()->IsJSBuiltinsObject();
4140}
4141
4142
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004143bool JSFunction::NeedsArgumentsAdaption() {
4144 return shared()->formal_parameter_count() !=
4145 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
4146}
4147
4148
4149bool JSFunction::IsOptimized() {
4150 return code()->kind() == Code::OPTIMIZED_FUNCTION;
4151}
4152
4153
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00004154bool JSFunction::IsOptimizable() {
4155 return code()->kind() == Code::FUNCTION && code()->optimizable();
4156}
4157
4158
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004159bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004160 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004161}
4162
4163
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004164Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004165 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004166}
4167
4168
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004169Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004170 return reinterpret_cast<Code*>(
4171 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004172}
4173
4174
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004175void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004176 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004177 Address entry = value->entry();
4178 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004179 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
4180 this,
4181 HeapObject::RawField(this, kCodeEntryOffset),
4182 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004183}
4184
4185
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004186void JSFunction::ReplaceCode(Code* code) {
4187 bool was_optimized = IsOptimized();
4188 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
4189
4190 set_code(code);
4191
4192 // Add/remove the function from the list of optimized functions for this
4193 // context based on the state change.
4194 if (!was_optimized && is_optimized) {
4195 context()->global_context()->AddOptimizedFunction(this);
4196 }
4197 if (was_optimized && !is_optimized) {
4198 context()->global_context()->RemoveOptimizedFunction(this);
4199 }
4200}
4201
4202
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004203Context* JSFunction::context() {
4204 return Context::cast(READ_FIELD(this, kContextOffset));
4205}
4206
4207
4208Object* JSFunction::unchecked_context() {
4209 return READ_FIELD(this, kContextOffset);
4210}
4211
4212
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004213SharedFunctionInfo* JSFunction::unchecked_shared() {
4214 return reinterpret_cast<SharedFunctionInfo*>(
4215 READ_FIELD(this, kSharedFunctionInfoOffset));
4216}
4217
4218
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004219void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004220 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004221 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004222 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004223}
4224
4225ACCESSORS(JSFunction, prototype_or_initial_map, Object,
4226 kPrototypeOrInitialMapOffset)
4227
4228
4229Map* JSFunction::initial_map() {
4230 return Map::cast(prototype_or_initial_map());
4231}
4232
4233
4234void JSFunction::set_initial_map(Map* value) {
4235 set_prototype_or_initial_map(value);
4236}
4237
4238
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004239MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
4240 Map* initial_map) {
4241 Context* global_context = context()->global_context();
4242 Object* array_function =
4243 global_context->get(Context::ARRAY_FUNCTION_INDEX);
4244 if (array_function->IsJSFunction() &&
4245 this == JSFunction::cast(array_function)) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004246 // Replace all of the cached initial array maps in the global context with
4247 // the appropriate transitioned elements kind maps.
4248 Heap* heap = GetHeap();
4249 MaybeObject* maybe_maps =
4250 heap->AllocateFixedArrayWithHoles(kElementsKindCount);
4251 FixedArray* maps;
4252 if (!maybe_maps->To(&maps)) return maybe_maps;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004253
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004254 Map* current_map = initial_map;
4255 ElementsKind kind = current_map->elements_kind();
4256 ASSERT(kind == GetInitialFastElementsKind());
4257 maps->set(kind, current_map);
4258 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
4259 i < kFastElementsKindCount; ++i) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004260 Map* new_map;
4261 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
4262 MaybeObject* maybe_new_map =
4263 current_map->CreateNextElementsTransition(next_kind);
4264 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
4265 maps->set(next_kind, new_map);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004266 current_map = new_map;
4267 }
4268 global_context->set_js_array_maps(maps);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004269 }
4270 set_initial_map(initial_map);
4271 return this;
4272}
4273
4274
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004275bool JSFunction::has_initial_map() {
4276 return prototype_or_initial_map()->IsMap();
4277}
4278
4279
4280bool JSFunction::has_instance_prototype() {
4281 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4282}
4283
4284
4285bool JSFunction::has_prototype() {
4286 return map()->has_non_instance_prototype() || has_instance_prototype();
4287}
4288
4289
4290Object* JSFunction::instance_prototype() {
4291 ASSERT(has_instance_prototype());
4292 if (has_initial_map()) return initial_map()->prototype();
4293 // When there is no initial map and the prototype is a JSObject, the
4294 // initial map field is used for the prototype field.
4295 return prototype_or_initial_map();
4296}
4297
4298
4299Object* JSFunction::prototype() {
4300 ASSERT(has_prototype());
4301 // If the function's prototype property has been set to a non-JSObject
4302 // value, that value is stored in the constructor field of the map.
4303 if (map()->has_non_instance_prototype()) return map()->constructor();
4304 return instance_prototype();
4305}
4306
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004307
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00004308bool JSFunction::should_have_prototype() {
4309 return map()->function_with_prototype();
4310}
4311
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004312
4313bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004314 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004315}
4316
4317
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004318FixedArray* JSFunction::literals() {
4319 ASSERT(!shared()->bound());
4320 return literals_or_bindings();
4321}
4322
4323
4324void JSFunction::set_literals(FixedArray* literals) {
4325 ASSERT(!shared()->bound());
4326 set_literals_or_bindings(literals);
4327}
4328
4329
4330FixedArray* JSFunction::function_bindings() {
4331 ASSERT(shared()->bound());
4332 return literals_or_bindings();
4333}
4334
4335
4336void JSFunction::set_function_bindings(FixedArray* bindings) {
4337 ASSERT(shared()->bound());
4338 // Bound function literal may be initialized to the empty fixed array
4339 // before the bindings are set.
4340 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4341 bindings->map() == GetHeap()->fixed_cow_array_map());
4342 set_literals_or_bindings(bindings);
4343}
4344
4345
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004346int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004347 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004348 return literals()->length();
4349}
4350
4351
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004352Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004353 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004354 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004355}
4356
4357
4358void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4359 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004360 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004361 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004362 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004363}
4364
4365
4366Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004367 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004368 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4369}
4370
4371
4372void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4373 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004374 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004375 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004376 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004377}
4378
4379
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004380ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004381ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004382ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4383ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4384
4385
4386void JSProxy::InitializeBody(int object_size, Object* value) {
4387 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4388 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4389 WRITE_FIELD(this, offset, value);
4390 }
4391}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004392
4393
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004394ACCESSORS(JSSet, table, Object, kTableOffset)
4395ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004396ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4397ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004398
4399
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004400Address Foreign::foreign_address() {
4401 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004402}
4403
4404
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004405void Foreign::set_foreign_address(Address value) {
4406 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004407}
4408
4409
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004410ACCESSORS(JSModule, context, Object, kContextOffset)
4411
4412
4413JSModule* JSModule::cast(Object* obj) {
4414 ASSERT(obj->IsJSModule());
4415 ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
4416 return reinterpret_cast<JSModule*>(obj);
4417}
4418
4419
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004420ACCESSORS(JSValue, value, Object, kValueOffset)
4421
4422
4423JSValue* JSValue::cast(Object* obj) {
4424 ASSERT(obj->IsJSValue());
4425 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4426 return reinterpret_cast<JSValue*>(obj);
4427}
4428
4429
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004430ACCESSORS(JSDate, value, Object, kValueOffset)
4431ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4432ACCESSORS(JSDate, year, Object, kYearOffset)
4433ACCESSORS(JSDate, month, Object, kMonthOffset)
4434ACCESSORS(JSDate, day, Object, kDayOffset)
4435ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4436ACCESSORS(JSDate, hour, Object, kHourOffset)
4437ACCESSORS(JSDate, min, Object, kMinOffset)
4438ACCESSORS(JSDate, sec, Object, kSecOffset)
4439
4440
4441JSDate* JSDate::cast(Object* obj) {
4442 ASSERT(obj->IsJSDate());
4443 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4444 return reinterpret_cast<JSDate*>(obj);
4445}
4446
4447
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004448ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4449ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4450ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4451ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4452ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4453SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4454SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4455
4456
4457JSMessageObject* JSMessageObject::cast(Object* obj) {
4458 ASSERT(obj->IsJSMessageObject());
4459 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4460 return reinterpret_cast<JSMessageObject*>(obj);
4461}
4462
4463
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004464INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004465ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004466ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004467ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004468ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004469ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00004470INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004471
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004472byte* Code::instruction_start() {
4473 return FIELD_ADDR(this, kHeaderSize);
4474}
4475
4476
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004477byte* Code::instruction_end() {
4478 return instruction_start() + instruction_size();
4479}
4480
4481
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004482int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004483 return RoundUp(instruction_size(), kObjectAlignment);
4484}
4485
4486
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004487FixedArray* Code::unchecked_deoptimization_data() {
4488 return reinterpret_cast<FixedArray*>(
4489 READ_FIELD(this, kDeoptimizationDataOffset));
4490}
4491
4492
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004493ByteArray* Code::unchecked_relocation_info() {
4494 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004495}
4496
4497
4498byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004499 return unchecked_relocation_info()->GetDataStartAddress();
4500}
4501
4502
4503int Code::relocation_size() {
4504 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004505}
4506
4507
4508byte* Code::entry() {
4509 return instruction_start();
4510}
4511
4512
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004513bool Code::contains(byte* inner_pointer) {
4514 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004515}
4516
4517
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004518ACCESSORS(JSArray, length, Object, kLengthOffset)
4519
4520
ager@chromium.org236ad962008-09-25 09:45:57 +00004521ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004522
4523
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004524JSRegExp::Type JSRegExp::TypeTag() {
4525 Object* data = this->data();
4526 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4527 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4528 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004529}
4530
4531
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004532JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4533 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4534 return static_cast<JSRegExp::Type>(smi->value());
4535}
4536
4537
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004538int JSRegExp::CaptureCount() {
4539 switch (TypeTag()) {
4540 case ATOM:
4541 return 0;
4542 case IRREGEXP:
4543 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4544 default:
4545 UNREACHABLE();
4546 return -1;
4547 }
4548}
4549
4550
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004551JSRegExp::Flags JSRegExp::GetFlags() {
4552 ASSERT(this->data()->IsFixedArray());
4553 Object* data = this->data();
4554 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4555 return Flags(smi->value());
4556}
4557
4558
4559String* JSRegExp::Pattern() {
4560 ASSERT(this->data()->IsFixedArray());
4561 Object* data = this->data();
4562 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4563 return pattern;
4564}
4565
4566
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004567Object* JSRegExp::DataAt(int index) {
4568 ASSERT(TypeTag() != NOT_COMPILED);
4569 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004570}
4571
4572
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004573Object* JSRegExp::DataAtUnchecked(int index) {
4574 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4575 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4576 return READ_FIELD(fa, offset);
4577}
4578
4579
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004580void JSRegExp::SetDataAt(int index, Object* value) {
4581 ASSERT(TypeTag() != NOT_COMPILED);
4582 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4583 FixedArray::cast(data())->set(index, value);
4584}
4585
4586
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004587void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4588 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4589 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4590 if (value->IsSmi()) {
4591 fa->set_unchecked(index, Smi::cast(value));
4592 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004593 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004594 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4595 }
4596}
4597
4598
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004599ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004600 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004601#if DEBUG
4602 FixedArrayBase* fixed_array =
4603 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4604 Map* map = fixed_array->map();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004605 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
4606 (map == GetHeap()->fixed_array_map() ||
4607 map == GetHeap()->fixed_cow_array_map())) ||
4608 (IsFastDoubleElementsKind(kind) &&
4609 (fixed_array->IsFixedDoubleArray() ||
4610 fixed_array == GetHeap()->empty_fixed_array())) ||
4611 (kind == DICTIONARY_ELEMENTS &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004612 fixed_array->IsFixedArray() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004613 fixed_array->IsDictionary()) ||
4614 (kind > DICTIONARY_ELEMENTS));
4615 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4616 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004617#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004618 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004619}
4620
4621
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004622ElementsAccessor* JSObject::GetElementsAccessor() {
4623 return ElementsAccessor::ForKind(GetElementsKind());
4624}
4625
4626
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004627bool JSObject::HasFastObjectElements() {
4628 return IsFastObjectElementsKind(GetElementsKind());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004629}
4630
4631
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004632bool JSObject::HasFastSmiElements() {
4633 return IsFastSmiElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004634}
4635
4636
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004637bool JSObject::HasFastSmiOrObjectElements() {
4638 return IsFastSmiOrObjectElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004639}
4640
4641
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004642bool JSObject::HasFastDoubleElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004643 return IsFastDoubleElementsKind(GetElementsKind());
4644}
4645
4646
4647bool JSObject::HasFastHoleyElements() {
4648 return IsFastHoleyElementsKind(GetElementsKind());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004649}
4650
4651
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004652bool JSObject::HasDictionaryElements() {
4653 return GetElementsKind() == DICTIONARY_ELEMENTS;
4654}
4655
4656
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004657bool JSObject::HasNonStrictArgumentsElements() {
4658 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4659}
4660
4661
ager@chromium.org3811b432009-10-28 14:53:37 +00004662bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004663 HeapObject* array = elements();
4664 ASSERT(array != NULL);
4665 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004666}
4667
4668
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004669#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4670bool JSObject::HasExternal##name##Elements() { \
4671 HeapObject* array = elements(); \
4672 ASSERT(array != NULL); \
4673 if (!array->IsHeapObject()) \
4674 return false; \
4675 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004676}
4677
4678
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004679EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4680EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4681EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4682EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4683 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4684EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4685EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4686 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4687EXTERNAL_ELEMENTS_CHECK(Float,
4688 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004689EXTERNAL_ELEMENTS_CHECK(Double,
4690 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004691EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004692
4693
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004694bool JSObject::HasNamedInterceptor() {
4695 return map()->has_named_interceptor();
4696}
4697
4698
4699bool JSObject::HasIndexedInterceptor() {
4700 return map()->has_indexed_interceptor();
4701}
4702
4703
lrn@chromium.org303ada72010-10-27 09:33:13 +00004704MaybeObject* JSObject::EnsureWritableFastElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004705 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004706 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004707 Isolate* isolate = GetIsolate();
4708 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004709 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004710 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4711 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004712 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4713 return maybe_writable_elems;
4714 }
4715 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004716 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004717 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004718 return writable_elems;
4719}
4720
4721
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004722StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004723 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004724 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004725}
4726
4727
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004728SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004729 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004730 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004731}
4732
4733
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004734bool String::IsHashFieldComputed(uint32_t field) {
4735 return (field & kHashNotComputedMask) == 0;
4736}
4737
4738
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004739bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004740 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004741}
4742
4743
4744uint32_t String::Hash() {
4745 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004746 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004747 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004748 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004749 return ComputeAndSetHash();
4750}
4751
4752
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004753StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004754 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004755 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004756 array_index_(0),
4757 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4758 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004759 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004760 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004761}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004762
4763
4764bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004765 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004766}
4767
4768
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004769void StringHasher::AddCharacter(uint32_t c) {
4770 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4771 AddSurrogatePair(c); // Not inlined.
4772 return;
4773 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004774 // Use the Jenkins one-at-a-time hash function to update the hash
4775 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004776 raw_running_hash_ += c;
4777 raw_running_hash_ += (raw_running_hash_ << 10);
4778 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004779 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004780 if (is_array_index_) {
4781 if (c < '0' || c > '9') {
4782 is_array_index_ = false;
4783 } else {
4784 int d = c - '0';
4785 if (is_first_char_) {
4786 is_first_char_ = false;
4787 if (c == '0' && length_ > 1) {
4788 is_array_index_ = false;
4789 return;
4790 }
4791 }
4792 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4793 is_array_index_ = false;
4794 } else {
4795 array_index_ = array_index_ * 10 + d;
4796 }
4797 }
4798 }
4799}
4800
4801
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004802void StringHasher::AddCharacterNoIndex(uint32_t c) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00004803 ASSERT(!is_array_index());
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004804 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4805 AddSurrogatePairNoIndex(c); // Not inlined.
4806 return;
4807 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004808 raw_running_hash_ += c;
4809 raw_running_hash_ += (raw_running_hash_ << 10);
4810 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4811}
4812
4813
4814uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004815 // Get the calculated raw hash value and do some more bit ops to distribute
4816 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004817 uint32_t result = raw_running_hash_;
4818 result += (result << 3);
4819 result ^= (result >> 11);
4820 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004821 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004822 result = 27;
4823 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004824 return result;
4825}
4826
4827
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004828template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004829uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4830 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004831 if (!hasher.has_trivial_hash()) {
4832 int i;
4833 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4834 hasher.AddCharacter(chars[i]);
4835 }
4836 for (; i < length; i++) {
4837 hasher.AddCharacterNoIndex(chars[i]);
4838 }
4839 }
4840 return hasher.GetHashField();
4841}
4842
4843
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004844bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004845 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004846 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4847 return false;
4848 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004849 return SlowAsArrayIndex(index);
4850}
4851
4852
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004853Object* JSReceiver::GetPrototype() {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004854 return map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004855}
4856
4857
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00004858Object* JSReceiver::GetConstructor() {
4859 return map()->constructor();
4860}
4861
4862
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004863bool JSReceiver::HasProperty(String* name) {
4864 if (IsJSProxy()) {
4865 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4866 }
4867 return GetPropertyAttribute(name) != ABSENT;
4868}
4869
4870
4871bool JSReceiver::HasLocalProperty(String* name) {
4872 if (IsJSProxy()) {
4873 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4874 }
4875 return GetLocalPropertyAttribute(name) != ABSENT;
4876}
4877
4878
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004879PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004880 return GetPropertyAttributeWithReceiver(this, key);
4881}
4882
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004883// TODO(504): this may be useful in other places too where JSGlobalProxy
4884// is used.
4885Object* JSObject::BypassGlobalProxy() {
4886 if (IsJSGlobalProxy()) {
4887 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004888 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004889 ASSERT(proto->IsJSGlobalObject());
4890 return proto;
4891 }
4892 return this;
4893}
4894
4895
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004896MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4897 return IsJSProxy()
4898 ? JSProxy::cast(this)->GetIdentityHash(flag)
4899 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004900}
4901
4902
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004903bool JSReceiver::HasElement(uint32_t index) {
4904 if (IsJSProxy()) {
4905 return JSProxy::cast(this)->HasElementWithHandler(index);
4906 }
4907 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004908}
4909
4910
4911bool AccessorInfo::all_can_read() {
4912 return BooleanBit::get(flag(), kAllCanReadBit);
4913}
4914
4915
4916void AccessorInfo::set_all_can_read(bool value) {
4917 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4918}
4919
4920
4921bool AccessorInfo::all_can_write() {
4922 return BooleanBit::get(flag(), kAllCanWriteBit);
4923}
4924
4925
4926void AccessorInfo::set_all_can_write(bool value) {
4927 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4928}
4929
4930
ager@chromium.org870a0b62008-11-04 11:43:05 +00004931bool AccessorInfo::prohibits_overwriting() {
4932 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4933}
4934
4935
4936void AccessorInfo::set_prohibits_overwriting(bool value) {
4937 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4938}
4939
4940
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004941PropertyAttributes AccessorInfo::property_attributes() {
4942 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4943}
4944
4945
4946void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004947 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004948}
4949
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004950
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004951bool AccessorInfo::IsCompatibleReceiver(Object* receiver) {
4952 Object* function_template = expected_receiver_type();
4953 if (!function_template->IsFunctionTemplateInfo()) return true;
4954 return receiver->IsInstanceOf(FunctionTemplateInfo::cast(function_template));
4955}
4956
4957
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004958template<typename Shape, typename Key>
4959void Dictionary<Shape, Key>::SetEntry(int entry,
4960 Object* key,
4961 Object* value) {
4962 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4963}
4964
4965
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004966template<typename Shape, typename Key>
4967void Dictionary<Shape, Key>::SetEntry(int entry,
4968 Object* key,
4969 Object* value,
4970 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004971 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004972 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004973 AssertNoAllocation no_gc;
4974 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004975 FixedArray::set(index, key, mode);
4976 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004977 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004978}
4979
4980
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004981bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4982 ASSERT(other->IsNumber());
4983 return key == static_cast<uint32_t>(other->Number());
4984}
4985
4986
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004987uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
4988 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004989}
4990
4991
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004992uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
4993 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004994 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004995 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004996}
4997
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004998uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
4999 return ComputeIntegerHash(key, seed);
5000}
5001
5002uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
5003 uint32_t seed,
5004 Object* other) {
5005 ASSERT(other->IsNumber());
5006 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
5007}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005008
5009MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
5010 return Isolate::Current()->heap()->NumberFromUint32(key);
5011}
5012
5013
5014bool StringDictionaryShape::IsMatch(String* key, Object* other) {
5015 // We know that all entries in a hash table had their hash keys created.
5016 // Use that knowledge to have fast failure.
5017 if (key->Hash() != String::cast(other)->Hash()) return false;
5018 return key->Equals(String::cast(other));
5019}
5020
5021
5022uint32_t StringDictionaryShape::Hash(String* key) {
5023 return key->Hash();
5024}
5025
5026
5027uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
5028 return String::cast(other)->Hash();
5029}
5030
5031
5032MaybeObject* StringDictionaryShape::AsObject(String* key) {
5033 return key;
5034}
5035
5036
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005037template <int entrysize>
5038bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
5039 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005040}
5041
5042
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005043template <int entrysize>
5044uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005045 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
5046 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005047}
5048
5049
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005050template <int entrysize>
5051uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
5052 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005053 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
5054 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005055}
5056
5057
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005058template <int entrysize>
5059MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005060 return key;
5061}
5062
5063
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005064void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005065 // No write barrier is needed since empty_fixed_array is not in new space.
5066 // Please note this function is used during marking:
5067 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00005068 // - IncrementalMarking::Step
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005069 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
5070 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005071}
5072
5073
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005074void JSArray::EnsureSize(int required_size) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005075 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005076 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005077 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
5078 if (elts->length() < required_size) {
5079 // Doubling in size would be overkill, but leave some slack to avoid
5080 // constantly growing.
5081 Expand(required_size + (required_size >> 3));
5082 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005083 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005084 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
5085 // Expand will allocate a new backing store in new space even if the size
5086 // we asked for isn't larger than what we had before.
5087 Expand(required_size);
5088 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005089}
5090
5091
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005092void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005093 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005094 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
5095}
5096
5097
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005098bool JSArray::AllowsSetElementsLength() {
5099 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
5100 ASSERT(result == !HasExternalArrayElements());
5101 return result;
5102}
5103
5104
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005105MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
5106 MaybeObject* maybe_result = EnsureCanContainElements(
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005107 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005108 if (maybe_result->IsFailure()) return maybe_result;
5109 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005110 IsFastDoubleElementsKind(GetElementsKind())) ||
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005111 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005112 (IsFastObjectElementsKind(GetElementsKind()) ||
5113 (IsFastSmiElementsKind(GetElementsKind()) &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005114 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00005115 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005116 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005117 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005118}
5119
5120
lrn@chromium.org303ada72010-10-27 09:33:13 +00005121MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005122 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005123 return GetHeap()->CopyFixedArray(this);
5124}
5125
5126
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005127MaybeObject* FixedDoubleArray::Copy() {
5128 if (length() == 0) return this;
5129 return GetHeap()->CopyFixedDoubleArray(this);
5130}
5131
5132
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005133void TypeFeedbackCells::SetAstId(int index, Smi* id) {
5134 set(1 + index * 2, id);
5135}
5136
5137
5138Smi* TypeFeedbackCells::AstId(int index) {
5139 return Smi::cast(get(1 + index * 2));
5140}
5141
5142
5143void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
5144 set(index * 2, cell);
5145}
5146
5147
5148JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
5149 return JSGlobalPropertyCell::cast(get(index * 2));
5150}
5151
5152
5153Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
5154 return isolate->factory()->the_hole_value();
5155}
5156
5157
5158Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
5159 return isolate->factory()->undefined_value();
5160}
5161
5162
5163Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
5164 return heap->raw_unchecked_the_hole_value();
5165}
5166
5167
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005168SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00005169SMI_ACCESSORS(TypeFeedbackInfo, ic_with_type_info_count,
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005170 kIcWithTypeinfoCountOffset)
5171ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
5172 kTypeFeedbackCellsOffset)
5173
5174
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00005175SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
5176
5177
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005178Relocatable::Relocatable(Isolate* isolate) {
5179 ASSERT(isolate == Isolate::Current());
5180 isolate_ = isolate;
5181 prev_ = isolate->relocatable_top();
5182 isolate->set_relocatable_top(this);
5183}
5184
5185
5186Relocatable::~Relocatable() {
5187 ASSERT(isolate_ == Isolate::Current());
5188 ASSERT_EQ(isolate_->relocatable_top(), this);
5189 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005190}
5191
5192
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005193int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
5194 return map->instance_size();
5195}
5196
5197
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005198void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005199 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005200 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005201}
5202
5203
5204template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005205void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005206 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005207 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005208}
5209
5210
5211void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
5212 typedef v8::String::ExternalAsciiStringResource Resource;
5213 v->VisitExternalAsciiString(
5214 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5215}
5216
5217
5218template<typename StaticVisitor>
5219void ExternalAsciiString::ExternalAsciiStringIterateBody() {
5220 typedef v8::String::ExternalAsciiStringResource Resource;
5221 StaticVisitor::VisitExternalAsciiString(
5222 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5223}
5224
5225
5226void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
5227 typedef v8::String::ExternalStringResource Resource;
5228 v->VisitExternalTwoByteString(
5229 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5230}
5231
5232
5233template<typename StaticVisitor>
5234void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
5235 typedef v8::String::ExternalStringResource Resource;
5236 StaticVisitor::VisitExternalTwoByteString(
5237 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5238}
5239
5240#define SLOT_ADDR(obj, offset) \
5241 reinterpret_cast<Object**>((obj)->address() + offset)
5242
5243template<int start_offset, int end_offset, int size>
5244void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
5245 HeapObject* obj,
5246 ObjectVisitor* v) {
5247 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
5248}
5249
5250
5251template<int start_offset>
5252void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
5253 int object_size,
5254 ObjectVisitor* v) {
5255 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
5256}
5257
5258#undef SLOT_ADDR
5259
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005260#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005261#undef CAST_ACCESSOR
5262#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005263#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005264#undef ACCESSORS_TO_SMI
5265#undef SMI_ACCESSORS
5266#undef BOOL_GETTER
5267#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005268#undef FIELD_ADDR
5269#undef READ_FIELD
5270#undef WRITE_FIELD
5271#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005272#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005273#undef READ_DOUBLE_FIELD
5274#undef WRITE_DOUBLE_FIELD
5275#undef READ_INT_FIELD
5276#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005277#undef READ_INTPTR_FIELD
5278#undef WRITE_INTPTR_FIELD
5279#undef READ_UINT32_FIELD
5280#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005281#undef READ_SHORT_FIELD
5282#undef WRITE_SHORT_FIELD
5283#undef READ_BYTE_FIELD
5284#undef WRITE_BYTE_FIELD
5285
5286
5287} } // namespace v8::internal
5288
5289#endif // V8_OBJECTS_INL_H_