blob: fbb0183815083b93fe410b498c968372f7f71df4 [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
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00001899Object* DescriptorArray::back_pointer_storage() {
1900 return READ_FIELD(this, kBackPointerStorageOffset);
danno@chromium.org40cb8782011-05-25 07:58:50 +00001901}
1902
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00001903
1904void DescriptorArray::set_back_pointer_storage(Object* value,
1905 WriteBarrierMode mode) {
1906 ASSERT(length() > kBackPointerStorageIndex);
1907 Heap* heap = GetHeap();
1908 WRITE_FIELD(this, kBackPointerStorageOffset, value);
1909 CONDITIONAL_WRITE_BARRIER(heap, this, kBackPointerStorageOffset, value, mode);
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001910}
1911
1912
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001913void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1914 int first,
1915 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001916 Object* tmp = array->get(first);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001917 NoIncrementalWriteBarrierSet(array, first, array->get(second));
1918 NoIncrementalWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001919}
1920
1921
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001922// Perform a binary search in a fixed array. Low and high are entry indices. If
1923// there are three entries in this array it should be called with low=0 and
1924// high=2.
1925template<typename T>
1926int BinarySearch(T* array, String* name, int low, int high) {
1927 uint32_t hash = name->Hash();
1928 int limit = high;
1929
1930 ASSERT(low <= high);
1931
1932 while (low != high) {
1933 int mid = (low + high) / 2;
1934 String* mid_name = array->GetKey(mid);
1935 uint32_t mid_hash = mid_name->Hash();
1936
1937 if (mid_hash >= hash) {
1938 high = mid;
1939 } else {
1940 low = mid + 1;
1941 }
1942 }
1943
1944 for (; low <= limit && array->GetKey(low)->Hash() == hash; ++low) {
1945 if (array->GetKey(low)->Equals(name)) return low;
1946 }
1947
1948 return T::kNotFound;
1949}
1950
1951
1952// Perform a linear search in this fixed array. len is the number of entry
1953// indices that are valid.
1954template<typename T>
1955int LinearSearch(T* array, SearchMode mode, String* name, int len) {
1956 uint32_t hash = name->Hash();
1957 for (int number = 0; number < len; number++) {
1958 String* entry = array->GetKey(number);
1959 uint32_t current_hash = entry->Hash();
1960 if (mode == EXPECT_SORTED && current_hash > hash) break;
1961 if (current_hash == hash && name->Equals(entry)) return number;
1962 }
1963 return T::kNotFound;
1964}
1965
1966
1967template<typename T>
1968int Search(T* array, String* name) {
1969 SLOW_ASSERT(array->IsSortedNoDuplicates());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001970
1971 // Check for empty descriptor array.
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001972 int nof = array->number_of_entries();
1973 if (nof == 0) return T::kNotFound;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001974
1975 // Fast case: do linear search for small arrays.
1976 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001977 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001978 return LinearSearch(array, EXPECT_SORTED, name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001979 }
1980
1981 // Slow case: perform binary search.
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001982 return BinarySearch(array, name, 0, nof - 1);
1983}
1984
1985
1986int DescriptorArray::Search(String* name) {
1987 return internal::Search(this, name);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001988}
1989
1990
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001991int DescriptorArray::SearchWithCache(String* name) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001992 DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache();
1993 int number = cache->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001994 if (number == DescriptorLookupCache::kAbsent) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001995 number = internal::Search(this, name);
1996 cache->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001997 }
1998 return number;
1999}
2000
2001
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002002TransitionArray* DescriptorArray::transitions() {
2003 ASSERT(MayContainTransitions());
2004 Object* array = get(kTransitionsIndex);
2005 return TransitionArray::cast(array);
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002006}
2007
2008
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002009void DescriptorArray::ClearTransitions() {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00002010 WRITE_FIELD(this, kTransitionsOffset, Smi::FromInt(0));
2011}
2012
2013
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002014void DescriptorArray::set_transitions(TransitionArray* transitions_array,
2015 WriteBarrierMode mode) {
2016 Heap* heap = GetHeap();
2017 WRITE_FIELD(this, kTransitionsOffset, transitions_array);
2018 CONDITIONAL_WRITE_BARRIER(
2019 heap, this, kTransitionsOffset, transitions_array, mode);
2020}
2021
2022
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002023Object** DescriptorArray::GetKeySlot(int descriptor_number) {
2024 ASSERT(descriptor_number < number_of_descriptors());
2025 return HeapObject::RawField(
2026 reinterpret_cast<HeapObject*>(this),
2027 OffsetOfElementAt(ToKeyIndex(descriptor_number)));
2028}
2029
2030
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002031String* DescriptorArray::GetKey(int descriptor_number) {
2032 ASSERT(descriptor_number < number_of_descriptors());
2033 return String::cast(get(ToKeyIndex(descriptor_number)));
2034}
2035
2036
verwaest@chromium.org37141392012-05-31 13:27:02 +00002037Object** DescriptorArray::GetValueSlot(int descriptor_number) {
2038 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002039 return HeapObject::RawField(
2040 reinterpret_cast<HeapObject*>(this),
2041 OffsetOfElementAt(ToValueIndex(descriptor_number)));
verwaest@chromium.org37141392012-05-31 13:27:02 +00002042}
2043
2044
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002045Object* DescriptorArray::GetValue(int descriptor_number) {
2046 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002047 return get(ToValueIndex(descriptor_number));
2048}
2049
2050
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002051PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002052 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002053 Object* details = get(ToDetailsIndex(descriptor_number));
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002054 return PropertyDetails(Smi::cast(details));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002055}
2056
2057
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002058PropertyType DescriptorArray::GetType(int descriptor_number) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002059 return GetDetails(descriptor_number).type();
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002060}
2061
2062
2063int DescriptorArray::GetFieldIndex(int descriptor_number) {
2064 return Descriptor::IndexFromValue(GetValue(descriptor_number));
2065}
2066
2067
2068JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
2069 return JSFunction::cast(GetValue(descriptor_number));
2070}
2071
2072
2073Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
2074 ASSERT(GetType(descriptor_number) == CALLBACKS);
2075 return GetValue(descriptor_number);
2076}
2077
2078
2079AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
2080 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002081 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002082 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002083}
2084
2085
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002086void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2087 desc->Init(GetKey(descriptor_number),
2088 GetValue(descriptor_number),
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002089 GetDetails(descriptor_number));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002090}
2091
2092
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002093void DescriptorArray::Set(int descriptor_number,
2094 Descriptor* desc,
2095 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002096 // Range check.
2097 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00002098 ASSERT(desc->GetDetails().index() > 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002099
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002100 NoIncrementalWriteBarrierSet(this,
2101 ToKeyIndex(descriptor_number),
2102 desc->GetKey());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002103 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002104 ToValueIndex(descriptor_number),
2105 desc->GetValue());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002106 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002107 ToDetailsIndex(descriptor_number),
2108 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002109}
2110
2111
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002112void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2113 int first, int second) {
2114 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002115 NoIncrementalWriteBarrierSwap(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002116 ToValueIndex(first),
2117 ToValueIndex(second));
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002118 NoIncrementalWriteBarrierSwap(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002119 ToDetailsIndex(first),
2120 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002121}
2122
2123
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002124FixedArray::WhitenessWitness::WhitenessWitness(FixedArray* array)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002125 : marking_(array->GetHeap()->incremental_marking()) {
2126 marking_->EnterNoMarkingScope();
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002127 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002128}
2129
2130
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002131FixedArray::WhitenessWitness::~WhitenessWitness() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002132 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002133}
2134
2135
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002136template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002137int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2138 const int kMinCapacity = 32;
2139 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2140 if (capacity < kMinCapacity) {
2141 capacity = kMinCapacity; // Guarantee min capacity.
2142 }
2143 return capacity;
2144}
2145
2146
2147template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002148int HashTable<Shape, Key>::FindEntry(Key key) {
2149 return FindEntry(GetIsolate(), key);
2150}
2151
2152
2153// Find entry for key otherwise return kNotFound.
2154template<typename Shape, typename Key>
2155int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2156 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002157 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002158 uint32_t count = 1;
2159 // EnsureCapacity will guarantee the hash table is never full.
2160 while (true) {
2161 Object* element = KeyAt(entry);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002162 // Empty entry.
2163 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2164 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002165 Shape::IsMatch(key, element)) return entry;
2166 entry = NextProbe(entry, count++, capacity);
2167 }
2168 return kNotFound;
2169}
2170
2171
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002172bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002173 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002174 if (!max_index_object->IsSmi()) return false;
2175 return 0 !=
2176 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2177}
2178
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002179uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002180 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002181 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002182 if (!max_index_object->IsSmi()) return 0;
2183 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2184 return value >> kRequiresSlowElementsTagSize;
2185}
2186
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002187void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002188 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002189}
2190
2191
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002192// ------------------------------------
2193// Cast operations
2194
2195
2196CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002197CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002198CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002199CAST_ACCESSOR(DeoptimizationInputData)
2200CAST_ACCESSOR(DeoptimizationOutputData)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002201CAST_ACCESSOR(TypeFeedbackCells)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002202CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002203CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002204CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002205CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002206CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002207CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002208CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002209CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002210CAST_ACCESSOR(String)
2211CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002212CAST_ACCESSOR(SeqAsciiString)
2213CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002214CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002215CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002216CAST_ACCESSOR(ExternalString)
2217CAST_ACCESSOR(ExternalAsciiString)
2218CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002219CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002220CAST_ACCESSOR(JSObject)
2221CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002222CAST_ACCESSOR(HeapObject)
2223CAST_ACCESSOR(HeapNumber)
2224CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002225CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002226CAST_ACCESSOR(SharedFunctionInfo)
2227CAST_ACCESSOR(Map)
2228CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002229CAST_ACCESSOR(GlobalObject)
2230CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002231CAST_ACCESSOR(JSGlobalObject)
2232CAST_ACCESSOR(JSBuiltinsObject)
2233CAST_ACCESSOR(Code)
2234CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002235CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002236CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002237CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002238CAST_ACCESSOR(JSSet)
2239CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002240CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002241CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002242CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002243CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002244CAST_ACCESSOR(ExternalArray)
2245CAST_ACCESSOR(ExternalByteArray)
2246CAST_ACCESSOR(ExternalUnsignedByteArray)
2247CAST_ACCESSOR(ExternalShortArray)
2248CAST_ACCESSOR(ExternalUnsignedShortArray)
2249CAST_ACCESSOR(ExternalIntArray)
2250CAST_ACCESSOR(ExternalUnsignedIntArray)
2251CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002252CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002253CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002254CAST_ACCESSOR(Struct)
2255
2256
2257#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2258 STRUCT_LIST(MAKE_STRUCT_CAST)
2259#undef MAKE_STRUCT_CAST
2260
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002261
2262template <typename Shape, typename Key>
2263HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002264 ASSERT(obj->IsHashTable());
2265 return reinterpret_cast<HashTable*>(obj);
2266}
2267
2268
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002269SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002270SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002271
ager@chromium.orgac091b72010-05-05 07:34:42 +00002272SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002273
2274
2275uint32_t String::hash_field() {
2276 return READ_UINT32_FIELD(this, kHashFieldOffset);
2277}
2278
2279
2280void String::set_hash_field(uint32_t value) {
2281 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002282#if V8_HOST_ARCH_64_BIT
2283 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2284#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002285}
2286
2287
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002288bool String::Equals(String* other) {
2289 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002290 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2291 return false;
2292 }
2293 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002294}
2295
2296
lrn@chromium.org303ada72010-10-27 09:33:13 +00002297MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002298 if (!StringShape(this).IsCons()) return this;
2299 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002300 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002301 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002302}
2303
2304
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002305String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002306 MaybeObject* flat = TryFlatten(pretenure);
2307 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002308 if (!flat->ToObject(&successfully_flattened)) return this;
2309 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002310}
2311
2312
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002313uint16_t String::Get(int index) {
2314 ASSERT(index >= 0 && index < length());
2315 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002316 case kSeqStringTag | kAsciiStringTag:
2317 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2318 case kSeqStringTag | kTwoByteStringTag:
2319 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2320 case kConsStringTag | kAsciiStringTag:
2321 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002322 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002323 case kExternalStringTag | kAsciiStringTag:
2324 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2325 case kExternalStringTag | kTwoByteStringTag:
2326 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002327 case kSlicedStringTag | kAsciiStringTag:
2328 case kSlicedStringTag | kTwoByteStringTag:
2329 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002330 default:
2331 break;
2332 }
2333
2334 UNREACHABLE();
2335 return 0;
2336}
2337
2338
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002339void String::Set(int index, uint16_t value) {
2340 ASSERT(index >= 0 && index < length());
2341 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002342
ager@chromium.org5ec48922009-05-05 07:25:34 +00002343 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002344 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2345 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002346}
2347
2348
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002349bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002350 if (!StringShape(this).IsCons()) return true;
2351 return ConsString::cast(this)->second()->length() == 0;
2352}
2353
2354
2355String* String::GetUnderlying() {
2356 // Giving direct access to underlying string only makes sense if the
2357 // wrapping string is already flattened.
2358 ASSERT(this->IsFlat());
2359 ASSERT(StringShape(this).IsIndirect());
2360 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2361 const int kUnderlyingOffset = SlicedString::kParentOffset;
2362 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002363}
2364
2365
ager@chromium.org7c537e22008-10-16 08:43:32 +00002366uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002367 ASSERT(index >= 0 && index < length());
2368 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2369}
2370
2371
ager@chromium.org7c537e22008-10-16 08:43:32 +00002372void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002373 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2374 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2375 static_cast<byte>(value));
2376}
2377
2378
ager@chromium.org7c537e22008-10-16 08:43:32 +00002379Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002380 return FIELD_ADDR(this, kHeaderSize);
2381}
2382
2383
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002384char* SeqAsciiString::GetChars() {
2385 return reinterpret_cast<char*>(GetCharsAddress());
2386}
2387
2388
ager@chromium.org7c537e22008-10-16 08:43:32 +00002389Address SeqTwoByteString::GetCharsAddress() {
2390 return FIELD_ADDR(this, kHeaderSize);
2391}
2392
2393
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002394uc16* SeqTwoByteString::GetChars() {
2395 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2396}
2397
2398
ager@chromium.org7c537e22008-10-16 08:43:32 +00002399uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002400 ASSERT(index >= 0 && index < length());
2401 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2402}
2403
2404
ager@chromium.org7c537e22008-10-16 08:43:32 +00002405void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002406 ASSERT(index >= 0 && index < length());
2407 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2408}
2409
2410
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002411int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002412 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002413}
2414
2415
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002416int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002417 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002418}
2419
2420
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002421String* SlicedString::parent() {
2422 return String::cast(READ_FIELD(this, kParentOffset));
2423}
2424
2425
2426void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002427 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002428 WRITE_FIELD(this, kParentOffset, parent);
2429}
2430
2431
2432SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2433
2434
ager@chromium.org870a0b62008-11-04 11:43:05 +00002435String* ConsString::first() {
2436 return String::cast(READ_FIELD(this, kFirstOffset));
2437}
2438
2439
2440Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002441 return READ_FIELD(this, kFirstOffset);
2442}
2443
2444
ager@chromium.org870a0b62008-11-04 11:43:05 +00002445void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002446 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002447 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002448}
2449
2450
ager@chromium.org870a0b62008-11-04 11:43:05 +00002451String* ConsString::second() {
2452 return String::cast(READ_FIELD(this, kSecondOffset));
2453}
2454
2455
2456Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002457 return READ_FIELD(this, kSecondOffset);
2458}
2459
2460
ager@chromium.org870a0b62008-11-04 11:43:05 +00002461void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002462 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002463 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002464}
2465
2466
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002467bool ExternalString::is_short() {
2468 InstanceType type = map()->instance_type();
2469 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002470}
2471
2472
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002473const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002474 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2475}
2476
2477
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002478void ExternalAsciiString::update_data_cache() {
2479 if (is_short()) return;
2480 const char** data_field =
2481 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2482 *data_field = resource()->data();
2483}
2484
2485
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002486void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002487 const ExternalAsciiString::Resource* resource) {
2488 *reinterpret_cast<const Resource**>(
2489 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002490 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002491}
2492
2493
2494const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002495 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002496}
2497
2498
2499uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2500 ASSERT(index >= 0 && index < length());
2501 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002502}
2503
2504
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002505const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002506 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2507}
2508
2509
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002510void ExternalTwoByteString::update_data_cache() {
2511 if (is_short()) return;
2512 const uint16_t** data_field =
2513 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2514 *data_field = resource()->data();
2515}
2516
2517
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002518void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002519 const ExternalTwoByteString::Resource* resource) {
2520 *reinterpret_cast<const Resource**>(
2521 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002522 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002523}
2524
2525
2526const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002527 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002528}
2529
2530
2531uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2532 ASSERT(index >= 0 && index < length());
2533 return GetChars()[index];
2534}
2535
2536
2537const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2538 unsigned start) {
2539 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002540}
2541
2542
ager@chromium.orgac091b72010-05-05 07:34:42 +00002543void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002544 set_finger_index(kEntriesIndex);
2545 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002546}
2547
2548
2549void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002550 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002551 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002552 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002553 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002554 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002555 MakeZeroSize();
2556}
2557
2558
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002559int JSFunctionResultCache::size() {
2560 return Smi::cast(get(kCacheSizeIndex))->value();
2561}
2562
2563
2564void JSFunctionResultCache::set_size(int size) {
2565 set(kCacheSizeIndex, Smi::FromInt(size));
2566}
2567
2568
2569int JSFunctionResultCache::finger_index() {
2570 return Smi::cast(get(kFingerIndex))->value();
2571}
2572
2573
2574void JSFunctionResultCache::set_finger_index(int finger_index) {
2575 set(kFingerIndex, Smi::FromInt(finger_index));
2576}
2577
2578
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002579byte ByteArray::get(int index) {
2580 ASSERT(index >= 0 && index < this->length());
2581 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2582}
2583
2584
2585void ByteArray::set(int index, byte value) {
2586 ASSERT(index >= 0 && index < this->length());
2587 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2588}
2589
2590
2591int ByteArray::get_int(int index) {
2592 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2593 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2594}
2595
2596
2597ByteArray* ByteArray::FromDataStartAddress(Address address) {
2598 ASSERT_TAG_ALIGNED(address);
2599 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2600}
2601
2602
2603Address ByteArray::GetDataStartAddress() {
2604 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2605}
2606
2607
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002608uint8_t* ExternalPixelArray::external_pixel_pointer() {
2609 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002610}
2611
2612
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002613uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002614 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002615 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002616 return ptr[index];
2617}
2618
2619
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002620MaybeObject* ExternalPixelArray::get(int index) {
2621 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2622}
2623
2624
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002625void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002626 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002627 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002628 ptr[index] = value;
2629}
2630
2631
ager@chromium.org3811b432009-10-28 14:53:37 +00002632void* ExternalArray::external_pointer() {
2633 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2634 return reinterpret_cast<void*>(ptr);
2635}
2636
2637
2638void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2639 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2640 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2641}
2642
2643
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002644int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002645 ASSERT((index >= 0) && (index < this->length()));
2646 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2647 return ptr[index];
2648}
2649
2650
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002651MaybeObject* ExternalByteArray::get(int index) {
2652 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2653}
2654
2655
ager@chromium.org3811b432009-10-28 14:53:37 +00002656void ExternalByteArray::set(int index, int8_t value) {
2657 ASSERT((index >= 0) && (index < this->length()));
2658 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2659 ptr[index] = value;
2660}
2661
2662
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002663uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002664 ASSERT((index >= 0) && (index < this->length()));
2665 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2666 return ptr[index];
2667}
2668
2669
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002670MaybeObject* ExternalUnsignedByteArray::get(int index) {
2671 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2672}
2673
2674
ager@chromium.org3811b432009-10-28 14:53:37 +00002675void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2676 ASSERT((index >= 0) && (index < this->length()));
2677 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2678 ptr[index] = value;
2679}
2680
2681
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002682int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002683 ASSERT((index >= 0) && (index < this->length()));
2684 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2685 return ptr[index];
2686}
2687
2688
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002689MaybeObject* ExternalShortArray::get(int index) {
2690 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2691}
2692
2693
ager@chromium.org3811b432009-10-28 14:53:37 +00002694void ExternalShortArray::set(int index, int16_t value) {
2695 ASSERT((index >= 0) && (index < this->length()));
2696 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2697 ptr[index] = value;
2698}
2699
2700
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002701uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002702 ASSERT((index >= 0) && (index < this->length()));
2703 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2704 return ptr[index];
2705}
2706
2707
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002708MaybeObject* ExternalUnsignedShortArray::get(int index) {
2709 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2710}
2711
2712
ager@chromium.org3811b432009-10-28 14:53:37 +00002713void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2714 ASSERT((index >= 0) && (index < this->length()));
2715 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2716 ptr[index] = value;
2717}
2718
2719
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002720int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002721 ASSERT((index >= 0) && (index < this->length()));
2722 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2723 return ptr[index];
2724}
2725
2726
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002727MaybeObject* ExternalIntArray::get(int index) {
2728 return GetHeap()->NumberFromInt32(get_scalar(index));
2729}
2730
2731
ager@chromium.org3811b432009-10-28 14:53:37 +00002732void ExternalIntArray::set(int index, int32_t value) {
2733 ASSERT((index >= 0) && (index < this->length()));
2734 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2735 ptr[index] = value;
2736}
2737
2738
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002739uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002740 ASSERT((index >= 0) && (index < this->length()));
2741 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2742 return ptr[index];
2743}
2744
2745
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002746MaybeObject* ExternalUnsignedIntArray::get(int index) {
2747 return GetHeap()->NumberFromUint32(get_scalar(index));
2748}
2749
2750
ager@chromium.org3811b432009-10-28 14:53:37 +00002751void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2752 ASSERT((index >= 0) && (index < this->length()));
2753 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2754 ptr[index] = value;
2755}
2756
2757
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002758float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002759 ASSERT((index >= 0) && (index < this->length()));
2760 float* ptr = static_cast<float*>(external_pointer());
2761 return ptr[index];
2762}
2763
2764
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002765MaybeObject* ExternalFloatArray::get(int index) {
2766 return GetHeap()->NumberFromDouble(get_scalar(index));
2767}
2768
2769
ager@chromium.org3811b432009-10-28 14:53:37 +00002770void ExternalFloatArray::set(int index, float value) {
2771 ASSERT((index >= 0) && (index < this->length()));
2772 float* ptr = static_cast<float*>(external_pointer());
2773 ptr[index] = value;
2774}
2775
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002776
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002777double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002778 ASSERT((index >= 0) && (index < this->length()));
2779 double* ptr = static_cast<double*>(external_pointer());
2780 return ptr[index];
2781}
2782
2783
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002784MaybeObject* ExternalDoubleArray::get(int index) {
2785 return GetHeap()->NumberFromDouble(get_scalar(index));
2786}
2787
2788
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002789void ExternalDoubleArray::set(int index, double value) {
2790 ASSERT((index >= 0) && (index < this->length()));
2791 double* ptr = static_cast<double*>(external_pointer());
2792 ptr[index] = value;
2793}
2794
2795
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002796int Map::visitor_id() {
2797 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2798}
2799
2800
2801void Map::set_visitor_id(int id) {
2802 ASSERT(0 <= id && id < 256);
2803 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2804}
2805
ager@chromium.org3811b432009-10-28 14:53:37 +00002806
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002807int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002808 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2809}
2810
2811
2812int Map::inobject_properties() {
2813 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002814}
2815
2816
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002817int Map::pre_allocated_property_fields() {
2818 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2819}
2820
2821
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002822int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002823 int instance_size = map->instance_size();
2824 if (instance_size != kVariableSizeSentinel) return instance_size;
2825 // We can ignore the "symbol" bit becase it is only set for symbols
2826 // and implies a string type.
2827 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002828 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002829 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002830 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002831 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002832 if (instance_type == ASCII_STRING_TYPE) {
2833 return SeqAsciiString::SizeFor(
2834 reinterpret_cast<SeqAsciiString*>(this)->length());
2835 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002836 if (instance_type == BYTE_ARRAY_TYPE) {
2837 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2838 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002839 if (instance_type == FREE_SPACE_TYPE) {
2840 return reinterpret_cast<FreeSpace*>(this)->size();
2841 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002842 if (instance_type == STRING_TYPE) {
2843 return SeqTwoByteString::SizeFor(
2844 reinterpret_cast<SeqTwoByteString*>(this)->length());
2845 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002846 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2847 return FixedDoubleArray::SizeFor(
2848 reinterpret_cast<FixedDoubleArray*>(this)->length());
2849 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002850 ASSERT(instance_type == CODE_TYPE);
2851 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002852}
2853
2854
2855void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002856 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002857 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002858 ASSERT(0 <= value && value < 256);
2859 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2860}
2861
2862
ager@chromium.org7c537e22008-10-16 08:43:32 +00002863void Map::set_inobject_properties(int value) {
2864 ASSERT(0 <= value && value < 256);
2865 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2866}
2867
2868
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002869void Map::set_pre_allocated_property_fields(int value) {
2870 ASSERT(0 <= value && value < 256);
2871 WRITE_BYTE_FIELD(this,
2872 kPreAllocatedPropertyFieldsOffset,
2873 static_cast<byte>(value));
2874}
2875
2876
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002877InstanceType Map::instance_type() {
2878 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2879}
2880
2881
2882void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002883 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2884}
2885
2886
2887int Map::unused_property_fields() {
2888 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2889}
2890
2891
2892void Map::set_unused_property_fields(int value) {
2893 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2894}
2895
2896
2897byte Map::bit_field() {
2898 return READ_BYTE_FIELD(this, kBitFieldOffset);
2899}
2900
2901
2902void Map::set_bit_field(byte value) {
2903 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2904}
2905
2906
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002907byte Map::bit_field2() {
2908 return READ_BYTE_FIELD(this, kBitField2Offset);
2909}
2910
2911
2912void Map::set_bit_field2(byte value) {
2913 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2914}
2915
2916
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002917void Map::set_non_instance_prototype(bool value) {
2918 if (value) {
2919 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2920 } else {
2921 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2922 }
2923}
2924
2925
2926bool Map::has_non_instance_prototype() {
2927 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2928}
2929
2930
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002931void Map::set_function_with_prototype(bool value) {
2932 if (value) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002933 set_bit_field3(bit_field3() | (1 << kFunctionWithPrototype));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002934 } else {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002935 set_bit_field3(bit_field3() & ~(1 << kFunctionWithPrototype));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002936 }
2937}
2938
2939
2940bool Map::function_with_prototype() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002941 return ((1 << kFunctionWithPrototype) & bit_field3()) != 0;
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002942}
2943
2944
ager@chromium.org870a0b62008-11-04 11:43:05 +00002945void Map::set_is_access_check_needed(bool access_check_needed) {
2946 if (access_check_needed) {
2947 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2948 } else {
2949 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2950 }
2951}
2952
2953
2954bool Map::is_access_check_needed() {
2955 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2956}
2957
2958
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002959void Map::set_is_extensible(bool value) {
2960 if (value) {
2961 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2962 } else {
2963 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2964 }
2965}
2966
2967bool Map::is_extensible() {
2968 return ((1 << kIsExtensible) & bit_field2()) != 0;
2969}
2970
2971
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002972void Map::set_attached_to_shared_function_info(bool value) {
2973 if (value) {
2974 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2975 } else {
2976 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2977 }
2978}
2979
2980bool Map::attached_to_shared_function_info() {
2981 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2982}
2983
2984
2985void Map::set_is_shared(bool value) {
2986 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002987 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002988 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002989 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002990 }
2991}
2992
2993bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002994 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002995}
2996
2997
2998JSFunction* Map::unchecked_constructor() {
2999 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
3000}
3001
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003002
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003003Code::Flags Code::flags() {
3004 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
3005}
3006
3007
3008void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003009 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003010 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003011 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
3012 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003013 ExtractArgumentsCountFromFlags(flags) >= 0);
3014 WRITE_INT_FIELD(this, kFlagsOffset, flags);
3015}
3016
3017
3018Code::Kind Code::kind() {
3019 return ExtractKindFromFlags(flags());
3020}
3021
3022
kasper.lund7276f142008-07-30 08:49:36 +00003023InlineCacheState Code::ic_state() {
3024 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003025 // Only allow uninitialized or debugger states for non-IC code
3026 // objects. This is used in the debugger to determine whether or not
3027 // a call to code object has been replaced with a debug break call.
3028 ASSERT(is_inline_cache_stub() ||
3029 result == UNINITIALIZED ||
3030 result == DEBUG_BREAK ||
3031 result == DEBUG_PREPARE_STEP_IN);
3032 return result;
3033}
3034
3035
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003036Code::ExtraICState Code::extra_ic_state() {
3037 ASSERT(is_inline_cache_stub());
3038 return ExtractExtraICStateFromFlags(flags());
3039}
3040
3041
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003042Code::StubType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003043 return ExtractTypeFromFlags(flags());
3044}
3045
3046
3047int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003048 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003049 return ExtractArgumentsCountFromFlags(flags());
3050}
3051
3052
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003053int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003054 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003055 kind() == UNARY_OP_IC ||
3056 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003057 kind() == COMPARE_IC ||
3058 kind() == TO_BOOLEAN_IC);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003059 return StubMajorKeyField::decode(
3060 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasper.lund7276f142008-07-30 08:49:36 +00003061}
3062
3063
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003064void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003065 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003066 kind() == UNARY_OP_IC ||
3067 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003068 kind() == COMPARE_IC ||
3069 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00003070 ASSERT(0 <= major && major < 256);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003071 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3072 int updated = StubMajorKeyField::update(previous, major);
3073 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003074}
3075
3076
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003077bool Code::is_pregenerated() {
3078 return kind() == STUB && IsPregeneratedField::decode(flags());
3079}
3080
3081
3082void Code::set_is_pregenerated(bool value) {
3083 ASSERT(kind() == STUB);
3084 Flags f = flags();
3085 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3086 set_flags(f);
3087}
3088
3089
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003090bool Code::optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003091 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003092 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3093}
3094
3095
3096void Code::set_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003097 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003098 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3099}
3100
3101
3102bool Code::has_deoptimization_support() {
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 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003106}
3107
3108
3109void Code::set_has_deoptimization_support(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003110 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003111 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3112 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3113 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3114}
3115
3116
3117bool Code::has_debug_break_slots() {
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 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3121}
3122
3123
3124void Code::set_has_debug_break_slots(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003125 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003126 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3127 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3128 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003129}
3130
3131
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003132bool Code::is_compiled_optimizable() {
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 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3136}
3137
3138
3139void Code::set_compiled_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003140 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003141 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3142 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3143 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3144}
3145
3146
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003147int Code::allow_osr_at_loop_nesting_level() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003148 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003149 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3150}
3151
3152
3153void Code::set_allow_osr_at_loop_nesting_level(int level) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003154 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003155 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3156 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3157}
3158
3159
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003160int Code::profiler_ticks() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003161 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003162 return READ_BYTE_FIELD(this, kProfilerTicksOffset);
3163}
3164
3165
3166void Code::set_profiler_ticks(int ticks) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003167 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003168 ASSERT(ticks < 256);
3169 WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
3170}
3171
3172
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003173unsigned Code::stack_slots() {
3174 ASSERT(kind() == OPTIMIZED_FUNCTION);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003175 return StackSlotsField::decode(
3176 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003177}
3178
3179
3180void Code::set_stack_slots(unsigned slots) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003181 CHECK(slots <= (1 << kStackSlotsBitCount));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003182 ASSERT(kind() == OPTIMIZED_FUNCTION);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003183 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3184 int updated = StackSlotsField::update(previous, slots);
3185 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003186}
3187
3188
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003189unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003190 ASSERT(kind() == OPTIMIZED_FUNCTION);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003191 return SafepointTableOffsetField::decode(
3192 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003193}
3194
3195
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003196void Code::set_safepoint_table_offset(unsigned offset) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003197 CHECK(offset <= (1 << kSafepointTableOffsetBitCount));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003198 ASSERT(kind() == OPTIMIZED_FUNCTION);
3199 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003200 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3201 int updated = SafepointTableOffsetField::update(previous, offset);
3202 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003203}
3204
3205
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003206unsigned Code::stack_check_table_offset() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003207 ASSERT_EQ(FUNCTION, kind());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003208 return StackCheckTableOffsetField::decode(
3209 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003210}
3211
3212
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003213void Code::set_stack_check_table_offset(unsigned offset) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003214 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003215 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003216 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3217 int updated = StackCheckTableOffsetField::update(previous, offset);
3218 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003219}
3220
3221
3222CheckType Code::check_type() {
3223 ASSERT(is_call_stub() || is_keyed_call_stub());
3224 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3225 return static_cast<CheckType>(type);
3226}
3227
3228
3229void Code::set_check_type(CheckType value) {
3230 ASSERT(is_call_stub() || is_keyed_call_stub());
3231 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3232}
3233
3234
danno@chromium.org40cb8782011-05-25 07:58:50 +00003235byte Code::unary_op_type() {
3236 ASSERT(is_unary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003237 return UnaryOpTypeField::decode(
3238 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003239}
3240
3241
danno@chromium.org40cb8782011-05-25 07:58:50 +00003242void Code::set_unary_op_type(byte value) {
3243 ASSERT(is_unary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003244 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3245 int updated = UnaryOpTypeField::update(previous, value);
3246 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003247}
3248
3249
danno@chromium.org40cb8782011-05-25 07:58:50 +00003250byte Code::binary_op_type() {
3251 ASSERT(is_binary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003252 return BinaryOpTypeField::decode(
3253 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003254}
3255
3256
danno@chromium.org40cb8782011-05-25 07:58:50 +00003257void Code::set_binary_op_type(byte value) {
3258 ASSERT(is_binary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003259 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3260 int updated = BinaryOpTypeField::update(previous, value);
3261 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003262}
3263
3264
danno@chromium.org40cb8782011-05-25 07:58:50 +00003265byte Code::binary_op_result_type() {
3266 ASSERT(is_binary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003267 return BinaryOpResultTypeField::decode(
3268 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003269}
3270
3271
danno@chromium.org40cb8782011-05-25 07:58:50 +00003272void Code::set_binary_op_result_type(byte value) {
3273 ASSERT(is_binary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003274 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3275 int updated = BinaryOpResultTypeField::update(previous, value);
3276 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003277}
3278
3279
3280byte Code::compare_state() {
3281 ASSERT(is_compare_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003282 return CompareStateField::decode(
3283 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003284}
3285
3286
3287void Code::set_compare_state(byte value) {
3288 ASSERT(is_compare_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003289 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3290 int updated = CompareStateField::update(previous, value);
3291 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003292}
3293
3294
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003295byte Code::compare_operation() {
3296 ASSERT(is_compare_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003297 return CompareOperationField::decode(
3298 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003299}
3300
3301
3302void Code::set_compare_operation(byte value) {
3303 ASSERT(is_compare_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003304 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3305 int updated = CompareOperationField::update(previous, value);
3306 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003307}
3308
3309
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003310byte Code::to_boolean_state() {
3311 ASSERT(is_to_boolean_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003312 return ToBooleanStateField::decode(
3313 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003314}
3315
3316
3317void Code::set_to_boolean_state(byte value) {
3318 ASSERT(is_to_boolean_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003319 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3320 int updated = ToBooleanStateField::update(previous, value);
3321 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003322}
3323
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003324
3325bool Code::has_function_cache() {
3326 ASSERT(kind() == STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003327 return HasFunctionCacheField::decode(
3328 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003329}
3330
3331
3332void Code::set_has_function_cache(bool flag) {
3333 ASSERT(kind() == STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003334 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3335 int updated = HasFunctionCacheField::update(previous, flag);
3336 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003337}
3338
3339
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003340bool Code::is_inline_cache_stub() {
3341 Kind kind = this->kind();
3342 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3343}
3344
3345
3346Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003347 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003348 ExtraICState extra_ic_state,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003349 StubType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003350 int argc,
3351 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003352 // Extra IC state is only allowed for call IC stubs or for store IC
3353 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003354 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003355 kind == CALL_IC ||
3356 kind == STORE_IC ||
3357 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003358 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003359 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003360 | ICStateField::encode(ic_state)
3361 | TypeField::encode(type)
3362 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003363 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003364 | CacheHolderField::encode(holder);
3365 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003366}
3367
3368
3369Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003370 StubType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003371 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003372 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003373 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003374 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003375}
3376
3377
3378Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003379 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003380}
3381
3382
kasper.lund7276f142008-07-30 08:49:36 +00003383InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003384 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003385}
3386
3387
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003388Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003389 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003390}
3391
3392
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003393Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003394 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003395}
3396
3397
3398int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003399 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003400}
3401
3402
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003403InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003404 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003405}
3406
3407
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003408Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003409 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003410 return static_cast<Flags>(bits);
3411}
3412
3413
ager@chromium.org8bb60582008-12-11 12:02:20 +00003414Code* Code::GetCodeFromTargetAddress(Address address) {
3415 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3416 // GetCodeFromTargetAddress might be called when marking objects during mark
3417 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3418 // Code::cast. Code::cast does not work when the object's map is
3419 // marked.
3420 Code* result = reinterpret_cast<Code*>(code);
3421 return result;
3422}
3423
3424
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003425Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3426 return HeapObject::
3427 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3428}
3429
3430
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003431Object* Map::prototype() {
3432 return READ_FIELD(this, kPrototypeOffset);
3433}
3434
3435
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003436void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003437 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003438 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003439 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003440}
3441
3442
danno@chromium.org40cb8782011-05-25 07:58:50 +00003443DescriptorArray* Map::instance_descriptors() {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003444 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset);
3445 if (!object->IsDescriptorArray()) {
3446 ASSERT(object->IsMap() || object->IsUndefined());
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003447 return GetHeap()->empty_descriptor_array();
danno@chromium.org40cb8782011-05-25 07:58:50 +00003448 } else {
3449 return DescriptorArray::cast(object);
3450 }
3451}
3452
3453
danno@chromium.org40cb8782011-05-25 07:58:50 +00003454void Map::set_instance_descriptors(DescriptorArray* value,
3455 WriteBarrierMode mode) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003456 Heap* heap = GetHeap();
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003457
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003458 if (value == heap->empty_descriptor_array()) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003459 ClearDescriptorArray(heap, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003460 return;
danno@chromium.org40cb8782011-05-25 07:58:50 +00003461 }
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003462
3463 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset);
3464
3465 if (object->IsDescriptorArray()) {
3466 value->set_back_pointer_storage(
3467 DescriptorArray::cast(object)->back_pointer_storage());
3468 } else {
3469 ASSERT(object->IsMap() || object->IsUndefined());
3470 value->set_back_pointer_storage(object);
3471 }
3472
danno@chromium.org40cb8782011-05-25 07:58:50 +00003473 ASSERT(!is_shared());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003474 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003475 CONDITIONAL_WRITE_BARRIER(
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003476 heap, this, kInstanceDescriptorsOrBackPointerOffset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003477}
3478
3479
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003480SMI_ACCESSORS(Map, bit_field3, kBitField3Offset)
danno@chromium.org40cb8782011-05-25 07:58:50 +00003481
3482
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003483void Map::ClearDescriptorArray(Heap* heap, WriteBarrierMode mode) {
3484 Object* back_pointer = GetBackPointer();
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003485#ifdef DEBUG
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003486 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset);
3487 if (object->IsDescriptorArray()) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003488 ZapTransitions();
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003489 } else {
3490 ASSERT(object->IsMap() || object->IsUndefined());
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003491 }
3492#endif
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003493 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, back_pointer);
3494 CONDITIONAL_WRITE_BARRIER(
3495 heap, this, kInstanceDescriptorsOrBackPointerOffset, back_pointer, mode);
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003496}
3497
3498
danno@chromium.org40cb8782011-05-25 07:58:50 +00003499
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003500Object* Map::GetBackPointer() {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003501 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset);
3502 if (object->IsDescriptorArray()) {
3503 return DescriptorArray::cast(object)->back_pointer_storage();
3504 } else {
3505 ASSERT(object->IsMap() || object->IsUndefined());
3506 return object;
3507 }
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003508}
3509
3510
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003511bool Map::HasElementsTransition() {
3512 return HasTransitionArray() && transitions()->HasElementsTransition();
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003513}
3514
3515
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003516bool Map::HasTransitionArray() {
3517 return instance_descriptors()->HasTransitionArray();
3518}
3519
3520
3521Map* Map::elements_transition_map() {
3522 return transitions()->elements_transition();
3523}
3524
3525
3526MaybeObject* Map::AddTransition(String* key, Object* value) {
3527 if (HasTransitionArray()) return transitions()->CopyInsert(key, value);
3528 return TransitionArray::NewWith(key, value);
3529}
3530
3531
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003532// If the map is using the empty descriptor array, install a new empty
3533// descriptor array that will contain an elements transition.
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003534static MaybeObject* AllowTransitions(Map* map) {
3535 if (map->instance_descriptors()->MayContainTransitions()) return map;
3536 DescriptorArray* descriptors;
3537 MaybeObject* maybe_descriptors =
3538 DescriptorArray::Allocate(0, DescriptorArray::CANNOT_BE_SHARED);
3539 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
3540 map->set_instance_descriptors(descriptors);
3541 return descriptors;
3542}
3543
3544
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003545// If the descriptor is using the empty transition array, install a new empty
3546// transition array that will have place for an element transition.
3547static MaybeObject* EnsureHasTransitionArray(Map* map) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003548 if (map->HasTransitionArray()) return map;
3549
3550 AllowTransitions(map);
3551
3552 TransitionArray* transitions;
3553 MaybeObject* maybe_transitions = TransitionArray::Allocate(0);
3554 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
3555 MaybeObject* added_transitions = map->set_transitions(transitions);
3556 if (added_transitions->IsFailure()) return added_transitions;
3557 return transitions;
3558}
3559
3560
3561MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003562 MaybeObject* allow_elements = EnsureHasTransitionArray(this);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003563 if (allow_elements->IsFailure()) return allow_elements;
3564 transitions()->set_elements_transition(transitioned_map);
3565 return this;
3566}
3567
3568
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003569FixedArray* Map::GetPrototypeTransitions() {
3570 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
3571 if (!transitions()->HasPrototypeTransitions()) {
3572 return GetHeap()->empty_fixed_array();
3573 }
3574 return transitions()->GetPrototypeTransitions();
3575}
3576
3577
3578MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
3579 MaybeObject* allow_prototype = EnsureHasTransitionArray(this);
3580 if (allow_prototype->IsFailure()) return allow_prototype;
3581#ifdef DEBUG
3582 if (HasPrototypeTransitions()) {
3583 ASSERT(GetPrototypeTransitions() != proto_transitions);
3584 ZapPrototypeTransitions();
3585 }
3586#endif
3587 transitions()->SetPrototypeTransitions(proto_transitions);
3588 return this;
3589}
3590
3591
3592bool Map::HasPrototypeTransitions() {
3593 return HasTransitionArray() && transitions()->HasPrototypeTransitions();
3594}
3595
3596
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003597TransitionArray* Map::transitions() {
3598 return instance_descriptors()->transitions();
3599}
3600
3601
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003602void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003603#ifdef DEBUG
3604 ZapTransitions();
3605#endif
3606 DescriptorArray* descriptors = instance_descriptors();
3607 if (descriptors->number_of_descriptors() == 0) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003608 ClearDescriptorArray(heap, mode);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003609 } else {
3610 descriptors->ClearTransitions();
3611 }
3612}
3613
3614
3615MaybeObject* Map::set_transitions(TransitionArray* transitions_array) {
3616 MaybeObject* allow_transitions = AllowTransitions(this);
3617 if (allow_transitions->IsFailure()) return allow_transitions;
3618#ifdef DEBUG
3619 if (HasTransitionArray()) {
3620 ASSERT(transitions() != transitions_array);
3621 ZapTransitions();
3622 }
3623#endif
3624 instance_descriptors()->set_transitions(transitions_array);
3625 return this;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003626}
3627
3628
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003629void Map::init_back_pointer(Object* undefined) {
3630 ASSERT(undefined->IsUndefined());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003631 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, undefined);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003632}
3633
3634
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003635void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003636 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
3637 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
3638 (value->IsMap() && GetBackPointer()->IsUndefined()));
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003639 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset);
3640 if (object->IsMap()) {
3641 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, value);
3642 CONDITIONAL_WRITE_BARRIER(
3643 GetHeap(), this, kInstanceDescriptorsOrBackPointerOffset, value, mode);
3644 } else {
3645 DescriptorArray::cast(object)->set_back_pointer_storage(value);
3646 }
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003647}
3648
3649
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003650// Can either be Smi (no transitions), normal transition array, or a transition
3651// array with the header overwritten as a Smi (thus iterating).
3652TransitionArray* Map::unchecked_transition_array() {
3653 ASSERT(HasTransitionArray());
3654 Object* object = *HeapObject::RawField(instance_descriptors(),
3655 DescriptorArray::kTransitionsOffset);
3656 ASSERT(!object->IsSmi());
3657 TransitionArray* transition_array = static_cast<TransitionArray*>(object);
3658 return transition_array;
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003659}
3660
3661
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003662HeapObject* Map::UncheckedPrototypeTransitions() {
3663 ASSERT(HasTransitionArray());
3664 ASSERT(unchecked_transition_array()->HasPrototypeTransitions());
3665 return unchecked_transition_array()->UncheckedPrototypeTransitions();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003666}
3667
3668
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003669ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003670ACCESSORS(Map, constructor, Object, kConstructorOffset)
3671
3672ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003673ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003674ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003675
3676ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3677ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003678ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003679
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003680ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003681
3682ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3683ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3684ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3685ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003686ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003687ACCESSORS(AccessorInfo, expected_receiver_type, Object,
3688 kExpectedReceiverTypeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003689
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003690ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3691ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3692
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003693ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3694ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3695ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3696
3697ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3698ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3699ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3700ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3701ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3702ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3703
3704ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3705ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3706
3707ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3708ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3709
3710ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3711ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003712ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3713 kPropertyAccessorsOffset)
3714ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3715 kPrototypeTemplateOffset)
3716ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3717ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3718 kNamedPropertyHandlerOffset)
3719ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3720 kIndexedPropertyHandlerOffset)
3721ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3722 kInstanceTemplateOffset)
3723ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3724ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003725ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3726 kInstanceCallHandlerOffset)
3727ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3728 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003729ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003730
3731ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003732ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3733 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003734
3735ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3736ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3737
3738ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3739
3740ACCESSORS(Script, source, Object, kSourceOffset)
3741ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003742ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003743ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
3744ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003745ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003746ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003747ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003748ACCESSORS_TO_SMI(Script, type, kTypeOffset)
3749ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
3750ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003751ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003752ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003753ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
3754 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003755
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003756#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003757ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3758ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3759ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3760ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3761
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003762ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
3763ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
3764ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003765ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003766#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003767
3768ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003769ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
3770 kOptimizedCodeMapOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003771ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3772ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003773ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3774 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003775ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003776ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3777ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003778ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003779ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3780 kThisPropertyAssignmentsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003781SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003782
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00003783
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003784BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3785 kHiddenPrototypeBit)
3786BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3787BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3788 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003789BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3790 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003791BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3792 kIsExpressionBit)
3793BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3794 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003795BOOL_GETTER(SharedFunctionInfo,
3796 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003797 has_only_simple_this_property_assignments,
3798 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003799BOOL_ACCESSORS(SharedFunctionInfo,
3800 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003801 allows_lazy_compilation,
3802 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003803BOOL_ACCESSORS(SharedFunctionInfo,
3804 compiler_hints,
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003805 allows_lazy_compilation_without_context,
3806 kAllowLazyCompilationWithoutContext)
3807BOOL_ACCESSORS(SharedFunctionInfo,
3808 compiler_hints,
whesse@chromium.org7b260152011-06-20 15:33:18 +00003809 uses_arguments,
3810 kUsesArguments)
3811BOOL_ACCESSORS(SharedFunctionInfo,
3812 compiler_hints,
3813 has_duplicate_parameters,
3814 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003815
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003816
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003817#if V8_HOST_ARCH_32_BIT
3818SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3819SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003820 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003821SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003822 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003823SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3824SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003825 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003826SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3827SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003828 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003829SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003830 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003831SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003832 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003833SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003834SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
3835SMI_ACCESSORS(SharedFunctionInfo,
3836 stress_deopt_counter,
3837 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003838#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003839
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003840#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003841 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003842 int holder::name() { \
3843 int value = READ_INT_FIELD(this, offset); \
3844 ASSERT(kHeapObjectTag == 1); \
3845 ASSERT((value & kHeapObjectTag) == 0); \
3846 return value >> 1; \
3847 } \
3848 void holder::set_##name(int value) { \
3849 ASSERT(kHeapObjectTag == 1); \
3850 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3851 (value & 0xC0000000) == 0x000000000); \
3852 WRITE_INT_FIELD(this, \
3853 offset, \
3854 (value << 1) & ~kHeapObjectTag); \
3855 }
3856
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003857#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3858 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003859 INT_ACCESSORS(holder, name, offset)
3860
3861
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003862PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003863PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3864 formal_parameter_count,
3865 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003866
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003867PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3868 expected_nof_properties,
3869 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003870PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3871
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003872PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3873PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3874 start_position_and_type,
3875 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003876
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003877PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3878 function_token_position,
3879 kFunctionTokenPositionOffset)
3880PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3881 compiler_hints,
3882 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003883
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003884PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3885 this_property_assignments_count,
3886 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003887PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003888
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003889PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, counters, kCountersOffset)
3890PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3891 stress_deopt_counter,
3892 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003893#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003894
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003895
3896int SharedFunctionInfo::construction_count() {
3897 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3898}
3899
3900
3901void SharedFunctionInfo::set_construction_count(int value) {
3902 ASSERT(0 <= value && value < 256);
3903 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3904}
3905
3906
whesse@chromium.org7b260152011-06-20 15:33:18 +00003907BOOL_ACCESSORS(SharedFunctionInfo,
3908 compiler_hints,
3909 live_objects_may_exist,
3910 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003911
3912
3913bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003914 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003915}
3916
3917
whesse@chromium.org7b260152011-06-20 15:33:18 +00003918BOOL_GETTER(SharedFunctionInfo,
3919 compiler_hints,
3920 optimization_disabled,
3921 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003922
3923
3924void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3925 set_compiler_hints(BooleanBit::set(compiler_hints(),
3926 kOptimizationDisabled,
3927 disable));
3928 // If disabling optimizations we reflect that in the code object so
3929 // it will not be counted as optimizable code.
3930 if ((code()->kind() == Code::FUNCTION) && disable) {
3931 code()->set_optimizable(false);
3932 }
3933}
3934
3935
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003936int SharedFunctionInfo::profiler_ticks() {
3937 if (code()->kind() != Code::FUNCTION) return 0;
3938 return code()->profiler_ticks();
3939}
3940
3941
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003942LanguageMode SharedFunctionInfo::language_mode() {
3943 int hints = compiler_hints();
3944 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3945 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3946 return EXTENDED_MODE;
3947 }
3948 return BooleanBit::get(hints, kStrictModeFunction)
3949 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003950}
3951
3952
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003953void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3954 // We only allow language mode transitions that go set the same language mode
3955 // again or go up in the chain:
3956 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3957 ASSERT(this->language_mode() == CLASSIC_MODE ||
3958 this->language_mode() == language_mode ||
3959 language_mode == EXTENDED_MODE);
3960 int hints = compiler_hints();
3961 hints = BooleanBit::set(
3962 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3963 hints = BooleanBit::set(
3964 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3965 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003966}
3967
3968
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003969bool SharedFunctionInfo::is_classic_mode() {
3970 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3971}
3972
3973BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3974 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003975BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3976BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3977 name_should_print_as_anonymous,
3978 kNameShouldPrintAsAnonymous)
3979BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3980BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00003981BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
3982BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
3983 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003984BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003985BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_cache, kDontCache)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003986
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003987void SharedFunctionInfo::BeforeVisitingPointers() {
3988 if (IsInobjectSlackTrackingInProgress()) DetachInitialMap();
3989
3990 // Flush optimized code map on major GC.
3991 // Note: we may experiment with rebuilding it or retaining entries
3992 // which should survive as we iterate through optimized functions
3993 // anyway.
3994 set_optimized_code_map(Smi::FromInt(0));
3995}
3996
3997
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003998ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3999ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
4000
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00004001ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
4002
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00004003bool Script::HasValidSource() {
4004 Object* src = this->source();
4005 if (!src->IsString()) return true;
4006 String* src_str = String::cast(src);
4007 if (!StringShape(src_str).IsExternal()) return true;
4008 if (src_str->IsAsciiRepresentation()) {
4009 return ExternalAsciiString::cast(src)->resource() != NULL;
4010 } else if (src_str->IsTwoByteRepresentation()) {
4011 return ExternalTwoByteString::cast(src)->resource() != NULL;
4012 }
4013 return true;
4014}
4015
4016
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00004017void SharedFunctionInfo::DontAdaptArguments() {
4018 ASSERT(code()->kind() == Code::BUILTIN);
4019 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
4020}
4021
4022
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004023int SharedFunctionInfo::start_position() {
4024 return start_position_and_type() >> kStartPositionShift;
4025}
4026
4027
4028void SharedFunctionInfo::set_start_position(int start_position) {
4029 set_start_position_and_type((start_position << kStartPositionShift)
4030 | (start_position_and_type() & ~kStartPositionMask));
4031}
4032
4033
4034Code* SharedFunctionInfo::code() {
4035 return Code::cast(READ_FIELD(this, kCodeOffset));
4036}
4037
4038
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004039Code* SharedFunctionInfo::unchecked_code() {
4040 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
4041}
4042
4043
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004044void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004045 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004046 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004047}
4048
4049
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004050ScopeInfo* SharedFunctionInfo::scope_info() {
4051 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00004052}
4053
4054
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004055void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00004056 WriteBarrierMode mode) {
4057 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004058 CONDITIONAL_WRITE_BARRIER(GetHeap(),
4059 this,
4060 kScopeInfoOffset,
4061 reinterpret_cast<Object*>(value),
4062 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00004063}
4064
4065
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004066bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004067 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004068 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004069}
4070
4071
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004072bool SharedFunctionInfo::IsApiFunction() {
4073 return function_data()->IsFunctionTemplateInfo();
4074}
4075
4076
4077FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
4078 ASSERT(IsApiFunction());
4079 return FunctionTemplateInfo::cast(function_data());
4080}
4081
4082
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004083bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00004084 return function_data()->IsSmi();
4085}
4086
4087
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004088BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
4089 ASSERT(HasBuiltinFunctionId());
4090 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004091}
4092
4093
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004094int SharedFunctionInfo::code_age() {
4095 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
4096}
4097
4098
4099void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00004100 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
4101 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004102}
4103
4104
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004105int SharedFunctionInfo::ic_age() {
4106 return ICAgeBits::decode(counters());
4107}
4108
4109
4110void SharedFunctionInfo::set_ic_age(int ic_age) {
4111 set_counters(ICAgeBits::update(counters(), ic_age));
4112}
4113
4114
4115int SharedFunctionInfo::deopt_count() {
4116 return DeoptCountBits::decode(counters());
4117}
4118
4119
4120void SharedFunctionInfo::set_deopt_count(int deopt_count) {
4121 set_counters(DeoptCountBits::update(counters(), deopt_count));
4122}
4123
4124
4125void SharedFunctionInfo::increment_deopt_count() {
4126 int value = counters();
4127 int deopt_count = DeoptCountBits::decode(value);
4128 deopt_count = (deopt_count + 1) & DeoptCountBits::kMax;
4129 set_counters(DeoptCountBits::update(value, deopt_count));
4130}
4131
4132
4133int SharedFunctionInfo::opt_reenable_tries() {
4134 return OptReenableTriesBits::decode(counters());
4135}
4136
4137
4138void SharedFunctionInfo::set_opt_reenable_tries(int tries) {
4139 set_counters(OptReenableTriesBits::update(counters(), tries));
4140}
4141
4142
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004143bool SharedFunctionInfo::has_deoptimization_support() {
4144 Code* code = this->code();
4145 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
4146}
4147
4148
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004149void SharedFunctionInfo::TryReenableOptimization() {
4150 int tries = opt_reenable_tries();
4151 set_opt_reenable_tries((tries + 1) & OptReenableTriesBits::kMax);
4152 // We reenable optimization whenever the number of tries is a large
4153 // enough power of 2.
4154 if (tries >= 16 && (((tries - 1) & tries) == 0)) {
4155 set_optimization_disabled(false);
4156 set_opt_count(0);
4157 set_deopt_count(0);
4158 code()->set_optimizable(true);
4159 }
4160}
4161
4162
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004163bool JSFunction::IsBuiltin() {
4164 return context()->global()->IsJSBuiltinsObject();
4165}
4166
4167
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004168bool JSFunction::NeedsArgumentsAdaption() {
4169 return shared()->formal_parameter_count() !=
4170 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
4171}
4172
4173
4174bool JSFunction::IsOptimized() {
4175 return code()->kind() == Code::OPTIMIZED_FUNCTION;
4176}
4177
4178
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00004179bool JSFunction::IsOptimizable() {
4180 return code()->kind() == Code::FUNCTION && code()->optimizable();
4181}
4182
4183
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004184bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004185 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004186}
4187
4188
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004189Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004190 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004191}
4192
4193
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004194Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004195 return reinterpret_cast<Code*>(
4196 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004197}
4198
4199
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004200void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004201 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004202 Address entry = value->entry();
4203 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004204 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
4205 this,
4206 HeapObject::RawField(this, kCodeEntryOffset),
4207 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004208}
4209
4210
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004211void JSFunction::ReplaceCode(Code* code) {
4212 bool was_optimized = IsOptimized();
4213 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
4214
4215 set_code(code);
4216
4217 // Add/remove the function from the list of optimized functions for this
4218 // context based on the state change.
4219 if (!was_optimized && is_optimized) {
4220 context()->global_context()->AddOptimizedFunction(this);
4221 }
4222 if (was_optimized && !is_optimized) {
4223 context()->global_context()->RemoveOptimizedFunction(this);
4224 }
4225}
4226
4227
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004228Context* JSFunction::context() {
4229 return Context::cast(READ_FIELD(this, kContextOffset));
4230}
4231
4232
4233Object* JSFunction::unchecked_context() {
4234 return READ_FIELD(this, kContextOffset);
4235}
4236
4237
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004238SharedFunctionInfo* JSFunction::unchecked_shared() {
4239 return reinterpret_cast<SharedFunctionInfo*>(
4240 READ_FIELD(this, kSharedFunctionInfoOffset));
4241}
4242
4243
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004244void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004245 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004246 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004247 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004248}
4249
4250ACCESSORS(JSFunction, prototype_or_initial_map, Object,
4251 kPrototypeOrInitialMapOffset)
4252
4253
4254Map* JSFunction::initial_map() {
4255 return Map::cast(prototype_or_initial_map());
4256}
4257
4258
4259void JSFunction::set_initial_map(Map* value) {
4260 set_prototype_or_initial_map(value);
4261}
4262
4263
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004264MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
4265 Map* initial_map) {
4266 Context* global_context = context()->global_context();
4267 Object* array_function =
4268 global_context->get(Context::ARRAY_FUNCTION_INDEX);
4269 if (array_function->IsJSFunction() &&
4270 this == JSFunction::cast(array_function)) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004271 // Replace all of the cached initial array maps in the global context with
4272 // the appropriate transitioned elements kind maps.
4273 Heap* heap = GetHeap();
4274 MaybeObject* maybe_maps =
4275 heap->AllocateFixedArrayWithHoles(kElementsKindCount);
4276 FixedArray* maps;
4277 if (!maybe_maps->To(&maps)) return maybe_maps;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004278
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004279 Map* current_map = initial_map;
4280 ElementsKind kind = current_map->elements_kind();
4281 ASSERT(kind == GetInitialFastElementsKind());
4282 maps->set(kind, current_map);
4283 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
4284 i < kFastElementsKindCount; ++i) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004285 Map* new_map;
4286 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
4287 MaybeObject* maybe_new_map =
4288 current_map->CreateNextElementsTransition(next_kind);
4289 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
4290 maps->set(next_kind, new_map);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004291 current_map = new_map;
4292 }
4293 global_context->set_js_array_maps(maps);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004294 }
4295 set_initial_map(initial_map);
4296 return this;
4297}
4298
4299
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004300bool JSFunction::has_initial_map() {
4301 return prototype_or_initial_map()->IsMap();
4302}
4303
4304
4305bool JSFunction::has_instance_prototype() {
4306 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4307}
4308
4309
4310bool JSFunction::has_prototype() {
4311 return map()->has_non_instance_prototype() || has_instance_prototype();
4312}
4313
4314
4315Object* JSFunction::instance_prototype() {
4316 ASSERT(has_instance_prototype());
4317 if (has_initial_map()) return initial_map()->prototype();
4318 // When there is no initial map and the prototype is a JSObject, the
4319 // initial map field is used for the prototype field.
4320 return prototype_or_initial_map();
4321}
4322
4323
4324Object* JSFunction::prototype() {
4325 ASSERT(has_prototype());
4326 // If the function's prototype property has been set to a non-JSObject
4327 // value, that value is stored in the constructor field of the map.
4328 if (map()->has_non_instance_prototype()) return map()->constructor();
4329 return instance_prototype();
4330}
4331
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004332
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00004333bool JSFunction::should_have_prototype() {
4334 return map()->function_with_prototype();
4335}
4336
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004337
4338bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004339 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004340}
4341
4342
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004343FixedArray* JSFunction::literals() {
4344 ASSERT(!shared()->bound());
4345 return literals_or_bindings();
4346}
4347
4348
4349void JSFunction::set_literals(FixedArray* literals) {
4350 ASSERT(!shared()->bound());
4351 set_literals_or_bindings(literals);
4352}
4353
4354
4355FixedArray* JSFunction::function_bindings() {
4356 ASSERT(shared()->bound());
4357 return literals_or_bindings();
4358}
4359
4360
4361void JSFunction::set_function_bindings(FixedArray* bindings) {
4362 ASSERT(shared()->bound());
4363 // Bound function literal may be initialized to the empty fixed array
4364 // before the bindings are set.
4365 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4366 bindings->map() == GetHeap()->fixed_cow_array_map());
4367 set_literals_or_bindings(bindings);
4368}
4369
4370
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004371int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004372 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004373 return literals()->length();
4374}
4375
4376
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004377Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004378 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004379 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004380}
4381
4382
4383void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4384 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004385 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004386 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004387 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004388}
4389
4390
4391Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004392 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004393 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4394}
4395
4396
4397void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4398 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004399 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004400 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004401 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004402}
4403
4404
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004405ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004406ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004407ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4408ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4409
4410
4411void JSProxy::InitializeBody(int object_size, Object* value) {
4412 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4413 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4414 WRITE_FIELD(this, offset, value);
4415 }
4416}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004417
4418
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004419ACCESSORS(JSSet, table, Object, kTableOffset)
4420ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004421ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4422ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004423
4424
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004425Address Foreign::foreign_address() {
4426 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004427}
4428
4429
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004430void Foreign::set_foreign_address(Address value) {
4431 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004432}
4433
4434
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004435ACCESSORS(JSModule, context, Object, kContextOffset)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004436ACCESSORS(JSModule, scope_info, ScopeInfo, kScopeInfoOffset)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004437
4438
4439JSModule* JSModule::cast(Object* obj) {
4440 ASSERT(obj->IsJSModule());
4441 ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
4442 return reinterpret_cast<JSModule*>(obj);
4443}
4444
4445
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004446ACCESSORS(JSValue, value, Object, kValueOffset)
4447
4448
4449JSValue* JSValue::cast(Object* obj) {
4450 ASSERT(obj->IsJSValue());
4451 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4452 return reinterpret_cast<JSValue*>(obj);
4453}
4454
4455
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004456ACCESSORS(JSDate, value, Object, kValueOffset)
4457ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4458ACCESSORS(JSDate, year, Object, kYearOffset)
4459ACCESSORS(JSDate, month, Object, kMonthOffset)
4460ACCESSORS(JSDate, day, Object, kDayOffset)
4461ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4462ACCESSORS(JSDate, hour, Object, kHourOffset)
4463ACCESSORS(JSDate, min, Object, kMinOffset)
4464ACCESSORS(JSDate, sec, Object, kSecOffset)
4465
4466
4467JSDate* JSDate::cast(Object* obj) {
4468 ASSERT(obj->IsJSDate());
4469 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4470 return reinterpret_cast<JSDate*>(obj);
4471}
4472
4473
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004474ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4475ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4476ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4477ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4478ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4479SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4480SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4481
4482
4483JSMessageObject* JSMessageObject::cast(Object* obj) {
4484 ASSERT(obj->IsJSMessageObject());
4485 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4486 return reinterpret_cast<JSMessageObject*>(obj);
4487}
4488
4489
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004490INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004491ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004492ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004493ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004494ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004495ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00004496INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004497
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004498byte* Code::instruction_start() {
4499 return FIELD_ADDR(this, kHeaderSize);
4500}
4501
4502
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004503byte* Code::instruction_end() {
4504 return instruction_start() + instruction_size();
4505}
4506
4507
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004508int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004509 return RoundUp(instruction_size(), kObjectAlignment);
4510}
4511
4512
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004513FixedArray* Code::unchecked_deoptimization_data() {
4514 return reinterpret_cast<FixedArray*>(
4515 READ_FIELD(this, kDeoptimizationDataOffset));
4516}
4517
4518
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004519ByteArray* Code::unchecked_relocation_info() {
4520 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004521}
4522
4523
4524byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004525 return unchecked_relocation_info()->GetDataStartAddress();
4526}
4527
4528
4529int Code::relocation_size() {
4530 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004531}
4532
4533
4534byte* Code::entry() {
4535 return instruction_start();
4536}
4537
4538
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004539bool Code::contains(byte* inner_pointer) {
4540 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004541}
4542
4543
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004544ACCESSORS(JSArray, length, Object, kLengthOffset)
4545
4546
ager@chromium.org236ad962008-09-25 09:45:57 +00004547ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004548
4549
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004550JSRegExp::Type JSRegExp::TypeTag() {
4551 Object* data = this->data();
4552 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4553 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4554 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004555}
4556
4557
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004558JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4559 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4560 return static_cast<JSRegExp::Type>(smi->value());
4561}
4562
4563
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004564int JSRegExp::CaptureCount() {
4565 switch (TypeTag()) {
4566 case ATOM:
4567 return 0;
4568 case IRREGEXP:
4569 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4570 default:
4571 UNREACHABLE();
4572 return -1;
4573 }
4574}
4575
4576
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004577JSRegExp::Flags JSRegExp::GetFlags() {
4578 ASSERT(this->data()->IsFixedArray());
4579 Object* data = this->data();
4580 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4581 return Flags(smi->value());
4582}
4583
4584
4585String* JSRegExp::Pattern() {
4586 ASSERT(this->data()->IsFixedArray());
4587 Object* data = this->data();
4588 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4589 return pattern;
4590}
4591
4592
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004593Object* JSRegExp::DataAt(int index) {
4594 ASSERT(TypeTag() != NOT_COMPILED);
4595 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004596}
4597
4598
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004599Object* JSRegExp::DataAtUnchecked(int index) {
4600 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4601 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4602 return READ_FIELD(fa, offset);
4603}
4604
4605
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004606void JSRegExp::SetDataAt(int index, Object* value) {
4607 ASSERT(TypeTag() != NOT_COMPILED);
4608 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4609 FixedArray::cast(data())->set(index, value);
4610}
4611
4612
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004613void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4614 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4615 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4616 if (value->IsSmi()) {
4617 fa->set_unchecked(index, Smi::cast(value));
4618 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004619 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004620 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4621 }
4622}
4623
4624
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004625ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004626 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004627#if DEBUG
4628 FixedArrayBase* fixed_array =
4629 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4630 Map* map = fixed_array->map();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004631 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
4632 (map == GetHeap()->fixed_array_map() ||
4633 map == GetHeap()->fixed_cow_array_map())) ||
4634 (IsFastDoubleElementsKind(kind) &&
4635 (fixed_array->IsFixedDoubleArray() ||
4636 fixed_array == GetHeap()->empty_fixed_array())) ||
4637 (kind == DICTIONARY_ELEMENTS &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004638 fixed_array->IsFixedArray() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004639 fixed_array->IsDictionary()) ||
4640 (kind > DICTIONARY_ELEMENTS));
4641 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4642 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004643#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004644 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004645}
4646
4647
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004648ElementsAccessor* JSObject::GetElementsAccessor() {
4649 return ElementsAccessor::ForKind(GetElementsKind());
4650}
4651
4652
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004653bool JSObject::HasFastObjectElements() {
4654 return IsFastObjectElementsKind(GetElementsKind());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004655}
4656
4657
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004658bool JSObject::HasFastSmiElements() {
4659 return IsFastSmiElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004660}
4661
4662
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004663bool JSObject::HasFastSmiOrObjectElements() {
4664 return IsFastSmiOrObjectElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004665}
4666
4667
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004668bool JSObject::HasFastDoubleElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004669 return IsFastDoubleElementsKind(GetElementsKind());
4670}
4671
4672
4673bool JSObject::HasFastHoleyElements() {
4674 return IsFastHoleyElementsKind(GetElementsKind());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004675}
4676
4677
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004678bool JSObject::HasDictionaryElements() {
4679 return GetElementsKind() == DICTIONARY_ELEMENTS;
4680}
4681
4682
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004683bool JSObject::HasNonStrictArgumentsElements() {
4684 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4685}
4686
4687
ager@chromium.org3811b432009-10-28 14:53:37 +00004688bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004689 HeapObject* array = elements();
4690 ASSERT(array != NULL);
4691 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004692}
4693
4694
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004695#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4696bool JSObject::HasExternal##name##Elements() { \
4697 HeapObject* array = elements(); \
4698 ASSERT(array != NULL); \
4699 if (!array->IsHeapObject()) \
4700 return false; \
4701 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004702}
4703
4704
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004705EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4706EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4707EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4708EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4709 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4710EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4711EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4712 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4713EXTERNAL_ELEMENTS_CHECK(Float,
4714 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004715EXTERNAL_ELEMENTS_CHECK(Double,
4716 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004717EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004718
4719
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004720bool JSObject::HasNamedInterceptor() {
4721 return map()->has_named_interceptor();
4722}
4723
4724
4725bool JSObject::HasIndexedInterceptor() {
4726 return map()->has_indexed_interceptor();
4727}
4728
4729
lrn@chromium.org303ada72010-10-27 09:33:13 +00004730MaybeObject* JSObject::EnsureWritableFastElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004731 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004732 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004733 Isolate* isolate = GetIsolate();
4734 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004735 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004736 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4737 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004738 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4739 return maybe_writable_elems;
4740 }
4741 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004742 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004743 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004744 return writable_elems;
4745}
4746
4747
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004748StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004749 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004750 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004751}
4752
4753
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004754SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004755 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004756 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004757}
4758
4759
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004760bool String::IsHashFieldComputed(uint32_t field) {
4761 return (field & kHashNotComputedMask) == 0;
4762}
4763
4764
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004765bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004766 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004767}
4768
4769
4770uint32_t String::Hash() {
4771 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004772 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004773 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004774 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004775 return ComputeAndSetHash();
4776}
4777
4778
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004779StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004780 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004781 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004782 array_index_(0),
4783 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4784 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004785 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004786 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004787}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004788
4789
4790bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004791 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004792}
4793
4794
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004795void StringHasher::AddCharacter(uint32_t c) {
4796 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4797 AddSurrogatePair(c); // Not inlined.
4798 return;
4799 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004800 // Use the Jenkins one-at-a-time hash function to update the hash
4801 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004802 raw_running_hash_ += c;
4803 raw_running_hash_ += (raw_running_hash_ << 10);
4804 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004805 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004806 if (is_array_index_) {
4807 if (c < '0' || c > '9') {
4808 is_array_index_ = false;
4809 } else {
4810 int d = c - '0';
4811 if (is_first_char_) {
4812 is_first_char_ = false;
4813 if (c == '0' && length_ > 1) {
4814 is_array_index_ = false;
4815 return;
4816 }
4817 }
4818 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4819 is_array_index_ = false;
4820 } else {
4821 array_index_ = array_index_ * 10 + d;
4822 }
4823 }
4824 }
4825}
4826
4827
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004828void StringHasher::AddCharacterNoIndex(uint32_t c) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00004829 ASSERT(!is_array_index());
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004830 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4831 AddSurrogatePairNoIndex(c); // Not inlined.
4832 return;
4833 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004834 raw_running_hash_ += c;
4835 raw_running_hash_ += (raw_running_hash_ << 10);
4836 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4837}
4838
4839
4840uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004841 // Get the calculated raw hash value and do some more bit ops to distribute
4842 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004843 uint32_t result = raw_running_hash_;
4844 result += (result << 3);
4845 result ^= (result >> 11);
4846 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004847 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004848 result = 27;
4849 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004850 return result;
4851}
4852
4853
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004854template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004855uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4856 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004857 if (!hasher.has_trivial_hash()) {
4858 int i;
4859 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4860 hasher.AddCharacter(chars[i]);
4861 }
4862 for (; i < length; i++) {
4863 hasher.AddCharacterNoIndex(chars[i]);
4864 }
4865 }
4866 return hasher.GetHashField();
4867}
4868
4869
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004870bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004871 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004872 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4873 return false;
4874 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004875 return SlowAsArrayIndex(index);
4876}
4877
4878
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004879Object* JSReceiver::GetPrototype() {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004880 return map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004881}
4882
4883
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00004884Object* JSReceiver::GetConstructor() {
4885 return map()->constructor();
4886}
4887
4888
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004889bool JSReceiver::HasProperty(String* name) {
4890 if (IsJSProxy()) {
4891 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4892 }
4893 return GetPropertyAttribute(name) != ABSENT;
4894}
4895
4896
4897bool JSReceiver::HasLocalProperty(String* name) {
4898 if (IsJSProxy()) {
4899 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4900 }
4901 return GetLocalPropertyAttribute(name) != ABSENT;
4902}
4903
4904
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004905PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004906 return GetPropertyAttributeWithReceiver(this, key);
4907}
4908
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004909// TODO(504): this may be useful in other places too where JSGlobalProxy
4910// is used.
4911Object* JSObject::BypassGlobalProxy() {
4912 if (IsJSGlobalProxy()) {
4913 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004914 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004915 ASSERT(proto->IsJSGlobalObject());
4916 return proto;
4917 }
4918 return this;
4919}
4920
4921
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004922MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4923 return IsJSProxy()
4924 ? JSProxy::cast(this)->GetIdentityHash(flag)
4925 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004926}
4927
4928
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004929bool JSReceiver::HasElement(uint32_t index) {
4930 if (IsJSProxy()) {
4931 return JSProxy::cast(this)->HasElementWithHandler(index);
4932 }
4933 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004934}
4935
4936
4937bool AccessorInfo::all_can_read() {
4938 return BooleanBit::get(flag(), kAllCanReadBit);
4939}
4940
4941
4942void AccessorInfo::set_all_can_read(bool value) {
4943 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4944}
4945
4946
4947bool AccessorInfo::all_can_write() {
4948 return BooleanBit::get(flag(), kAllCanWriteBit);
4949}
4950
4951
4952void AccessorInfo::set_all_can_write(bool value) {
4953 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4954}
4955
4956
ager@chromium.org870a0b62008-11-04 11:43:05 +00004957bool AccessorInfo::prohibits_overwriting() {
4958 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4959}
4960
4961
4962void AccessorInfo::set_prohibits_overwriting(bool value) {
4963 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4964}
4965
4966
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004967PropertyAttributes AccessorInfo::property_attributes() {
4968 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4969}
4970
4971
4972void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004973 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004974}
4975
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004976
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004977bool AccessorInfo::IsCompatibleReceiver(Object* receiver) {
4978 Object* function_template = expected_receiver_type();
4979 if (!function_template->IsFunctionTemplateInfo()) return true;
4980 return receiver->IsInstanceOf(FunctionTemplateInfo::cast(function_template));
4981}
4982
4983
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004984template<typename Shape, typename Key>
4985void Dictionary<Shape, Key>::SetEntry(int entry,
4986 Object* key,
4987 Object* value) {
4988 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4989}
4990
4991
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004992template<typename Shape, typename Key>
4993void Dictionary<Shape, Key>::SetEntry(int entry,
4994 Object* key,
4995 Object* value,
4996 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004997 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004998 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004999 AssertNoAllocation no_gc;
5000 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005001 FixedArray::set(index, key, mode);
5002 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005003 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005004}
5005
5006
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005007bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
5008 ASSERT(other->IsNumber());
5009 return key == static_cast<uint32_t>(other->Number());
5010}
5011
5012
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005013uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
5014 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005015}
5016
5017
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005018uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
5019 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005020 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005021 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005022}
5023
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005024uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
5025 return ComputeIntegerHash(key, seed);
5026}
5027
5028uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
5029 uint32_t seed,
5030 Object* other) {
5031 ASSERT(other->IsNumber());
5032 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
5033}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005034
5035MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
5036 return Isolate::Current()->heap()->NumberFromUint32(key);
5037}
5038
5039
5040bool StringDictionaryShape::IsMatch(String* key, Object* other) {
5041 // We know that all entries in a hash table had their hash keys created.
5042 // Use that knowledge to have fast failure.
5043 if (key->Hash() != String::cast(other)->Hash()) return false;
5044 return key->Equals(String::cast(other));
5045}
5046
5047
5048uint32_t StringDictionaryShape::Hash(String* key) {
5049 return key->Hash();
5050}
5051
5052
5053uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
5054 return String::cast(other)->Hash();
5055}
5056
5057
5058MaybeObject* StringDictionaryShape::AsObject(String* key) {
5059 return key;
5060}
5061
5062
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005063template <int entrysize>
5064bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
5065 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005066}
5067
5068
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005069template <int entrysize>
5070uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005071 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
5072 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005073}
5074
5075
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005076template <int entrysize>
5077uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
5078 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005079 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
5080 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005081}
5082
5083
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005084template <int entrysize>
5085MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005086 return key;
5087}
5088
5089
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005090void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005091 // No write barrier is needed since empty_fixed_array is not in new space.
5092 // Please note this function is used during marking:
5093 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00005094 // - IncrementalMarking::Step
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005095 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
5096 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005097}
5098
5099
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005100void JSArray::EnsureSize(int required_size) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005101 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005102 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005103 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
5104 if (elts->length() < required_size) {
5105 // Doubling in size would be overkill, but leave some slack to avoid
5106 // constantly growing.
5107 Expand(required_size + (required_size >> 3));
5108 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005109 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005110 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
5111 // Expand will allocate a new backing store in new space even if the size
5112 // we asked for isn't larger than what we had before.
5113 Expand(required_size);
5114 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005115}
5116
5117
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005118void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005119 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005120 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
5121}
5122
5123
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005124bool JSArray::AllowsSetElementsLength() {
5125 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
5126 ASSERT(result == !HasExternalArrayElements());
5127 return result;
5128}
5129
5130
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005131MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
5132 MaybeObject* maybe_result = EnsureCanContainElements(
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005133 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005134 if (maybe_result->IsFailure()) return maybe_result;
5135 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005136 IsFastDoubleElementsKind(GetElementsKind())) ||
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005137 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005138 (IsFastObjectElementsKind(GetElementsKind()) ||
5139 (IsFastSmiElementsKind(GetElementsKind()) &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005140 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00005141 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005142 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005143 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005144}
5145
5146
lrn@chromium.org303ada72010-10-27 09:33:13 +00005147MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005148 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005149 return GetHeap()->CopyFixedArray(this);
5150}
5151
5152
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005153MaybeObject* FixedDoubleArray::Copy() {
5154 if (length() == 0) return this;
5155 return GetHeap()->CopyFixedDoubleArray(this);
5156}
5157
5158
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005159void TypeFeedbackCells::SetAstId(int index, Smi* id) {
5160 set(1 + index * 2, id);
5161}
5162
5163
5164Smi* TypeFeedbackCells::AstId(int index) {
5165 return Smi::cast(get(1 + index * 2));
5166}
5167
5168
5169void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
5170 set(index * 2, cell);
5171}
5172
5173
5174JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
5175 return JSGlobalPropertyCell::cast(get(index * 2));
5176}
5177
5178
5179Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
5180 return isolate->factory()->the_hole_value();
5181}
5182
5183
5184Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
5185 return isolate->factory()->undefined_value();
5186}
5187
5188
5189Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
5190 return heap->raw_unchecked_the_hole_value();
5191}
5192
5193
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005194SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00005195SMI_ACCESSORS(TypeFeedbackInfo, ic_with_type_info_count,
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005196 kIcWithTypeinfoCountOffset)
5197ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
5198 kTypeFeedbackCellsOffset)
5199
5200
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00005201SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
5202
5203
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005204Relocatable::Relocatable(Isolate* isolate) {
5205 ASSERT(isolate == Isolate::Current());
5206 isolate_ = isolate;
5207 prev_ = isolate->relocatable_top();
5208 isolate->set_relocatable_top(this);
5209}
5210
5211
5212Relocatable::~Relocatable() {
5213 ASSERT(isolate_ == Isolate::Current());
5214 ASSERT_EQ(isolate_->relocatable_top(), this);
5215 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005216}
5217
5218
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005219int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
5220 return map->instance_size();
5221}
5222
5223
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005224void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005225 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005226 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005227}
5228
5229
5230template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005231void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005232 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005233 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005234}
5235
5236
5237void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
5238 typedef v8::String::ExternalAsciiStringResource Resource;
5239 v->VisitExternalAsciiString(
5240 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5241}
5242
5243
5244template<typename StaticVisitor>
5245void ExternalAsciiString::ExternalAsciiStringIterateBody() {
5246 typedef v8::String::ExternalAsciiStringResource Resource;
5247 StaticVisitor::VisitExternalAsciiString(
5248 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5249}
5250
5251
5252void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
5253 typedef v8::String::ExternalStringResource Resource;
5254 v->VisitExternalTwoByteString(
5255 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5256}
5257
5258
5259template<typename StaticVisitor>
5260void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
5261 typedef v8::String::ExternalStringResource Resource;
5262 StaticVisitor::VisitExternalTwoByteString(
5263 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5264}
5265
5266#define SLOT_ADDR(obj, offset) \
5267 reinterpret_cast<Object**>((obj)->address() + offset)
5268
5269template<int start_offset, int end_offset, int size>
5270void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
5271 HeapObject* obj,
5272 ObjectVisitor* v) {
5273 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
5274}
5275
5276
5277template<int start_offset>
5278void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
5279 int object_size,
5280 ObjectVisitor* v) {
5281 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
5282}
5283
5284#undef SLOT_ADDR
5285
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005286#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005287#undef CAST_ACCESSOR
5288#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005289#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005290#undef ACCESSORS_TO_SMI
5291#undef SMI_ACCESSORS
5292#undef BOOL_GETTER
5293#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005294#undef FIELD_ADDR
5295#undef READ_FIELD
5296#undef WRITE_FIELD
5297#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005298#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005299#undef READ_DOUBLE_FIELD
5300#undef WRITE_DOUBLE_FIELD
5301#undef READ_INT_FIELD
5302#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005303#undef READ_INTPTR_FIELD
5304#undef WRITE_INTPTR_FIELD
5305#undef READ_UINT32_FIELD
5306#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005307#undef READ_SHORT_FIELD
5308#undef WRITE_SHORT_FIELD
5309#undef READ_BYTE_FIELD
5310#undef WRITE_BYTE_FIELD
5311
5312
5313} } // namespace v8::internal
5314
5315#endif // V8_OBJECTS_INL_H_