blob: 23fb2133468afb020bff452f4e9163c6e904bd58 [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());
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00002098 ASSERT(desc->GetDetails().index() <= number_of_descriptors());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00002099 ASSERT(desc->GetDetails().index() > 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002100
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002101 NoIncrementalWriteBarrierSet(this,
2102 ToKeyIndex(descriptor_number),
2103 desc->GetKey());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002104 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002105 ToValueIndex(descriptor_number),
2106 desc->GetValue());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002107 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002108 ToDetailsIndex(descriptor_number),
2109 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002110}
2111
2112
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00002113void DescriptorArray::Append(Descriptor* desc,
2114 const WhitenessWitness& witness) {
2115 int descriptor_number = NumberOfSetDescriptors();
2116 int enumeration_index = descriptor_number + 1;
2117 desc->SetEnumerationIndex(enumeration_index);
2118 Set(descriptor_number, desc, witness);
2119 SetLastAdded(descriptor_number);
2120}
2121
2122
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002123void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2124 int first, int second) {
2125 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002126 NoIncrementalWriteBarrierSwap(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002127 ToValueIndex(first),
2128 ToValueIndex(second));
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002129 NoIncrementalWriteBarrierSwap(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002130 ToDetailsIndex(first),
2131 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002132}
2133
2134
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002135FixedArray::WhitenessWitness::WhitenessWitness(FixedArray* array)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002136 : marking_(array->GetHeap()->incremental_marking()) {
2137 marking_->EnterNoMarkingScope();
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002138 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002139}
2140
2141
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002142FixedArray::WhitenessWitness::~WhitenessWitness() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002143 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002144}
2145
2146
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002147template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002148int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2149 const int kMinCapacity = 32;
2150 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2151 if (capacity < kMinCapacity) {
2152 capacity = kMinCapacity; // Guarantee min capacity.
2153 }
2154 return capacity;
2155}
2156
2157
2158template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002159int HashTable<Shape, Key>::FindEntry(Key key) {
2160 return FindEntry(GetIsolate(), key);
2161}
2162
2163
2164// Find entry for key otherwise return kNotFound.
2165template<typename Shape, typename Key>
2166int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2167 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002168 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002169 uint32_t count = 1;
2170 // EnsureCapacity will guarantee the hash table is never full.
2171 while (true) {
2172 Object* element = KeyAt(entry);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002173 // Empty entry.
2174 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2175 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002176 Shape::IsMatch(key, element)) return entry;
2177 entry = NextProbe(entry, count++, capacity);
2178 }
2179 return kNotFound;
2180}
2181
2182
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002183bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002184 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002185 if (!max_index_object->IsSmi()) return false;
2186 return 0 !=
2187 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2188}
2189
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002190uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002191 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002192 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002193 if (!max_index_object->IsSmi()) return 0;
2194 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2195 return value >> kRequiresSlowElementsTagSize;
2196}
2197
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002198void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002199 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002200}
2201
2202
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002203// ------------------------------------
2204// Cast operations
2205
2206
2207CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002208CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002209CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002210CAST_ACCESSOR(DeoptimizationInputData)
2211CAST_ACCESSOR(DeoptimizationOutputData)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002212CAST_ACCESSOR(TypeFeedbackCells)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002213CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002214CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002215CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002216CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002217CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002218CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002219CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002220CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002221CAST_ACCESSOR(String)
2222CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002223CAST_ACCESSOR(SeqAsciiString)
2224CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002225CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002226CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002227CAST_ACCESSOR(ExternalString)
2228CAST_ACCESSOR(ExternalAsciiString)
2229CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002230CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002231CAST_ACCESSOR(JSObject)
2232CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002233CAST_ACCESSOR(HeapObject)
2234CAST_ACCESSOR(HeapNumber)
2235CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002236CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002237CAST_ACCESSOR(SharedFunctionInfo)
2238CAST_ACCESSOR(Map)
2239CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002240CAST_ACCESSOR(GlobalObject)
2241CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002242CAST_ACCESSOR(JSGlobalObject)
2243CAST_ACCESSOR(JSBuiltinsObject)
2244CAST_ACCESSOR(Code)
2245CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002246CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002247CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002248CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002249CAST_ACCESSOR(JSSet)
2250CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002251CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002252CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002253CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002254CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002255CAST_ACCESSOR(ExternalArray)
2256CAST_ACCESSOR(ExternalByteArray)
2257CAST_ACCESSOR(ExternalUnsignedByteArray)
2258CAST_ACCESSOR(ExternalShortArray)
2259CAST_ACCESSOR(ExternalUnsignedShortArray)
2260CAST_ACCESSOR(ExternalIntArray)
2261CAST_ACCESSOR(ExternalUnsignedIntArray)
2262CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002263CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002264CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002265CAST_ACCESSOR(Struct)
2266
2267
2268#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2269 STRUCT_LIST(MAKE_STRUCT_CAST)
2270#undef MAKE_STRUCT_CAST
2271
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002272
2273template <typename Shape, typename Key>
2274HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002275 ASSERT(obj->IsHashTable());
2276 return reinterpret_cast<HashTable*>(obj);
2277}
2278
2279
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002280SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002281SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002282
ager@chromium.orgac091b72010-05-05 07:34:42 +00002283SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002284
2285
2286uint32_t String::hash_field() {
2287 return READ_UINT32_FIELD(this, kHashFieldOffset);
2288}
2289
2290
2291void String::set_hash_field(uint32_t value) {
2292 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002293#if V8_HOST_ARCH_64_BIT
2294 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2295#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002296}
2297
2298
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002299bool String::Equals(String* other) {
2300 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002301 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2302 return false;
2303 }
2304 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002305}
2306
2307
lrn@chromium.org303ada72010-10-27 09:33:13 +00002308MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002309 if (!StringShape(this).IsCons()) return this;
2310 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002311 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002312 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002313}
2314
2315
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002316String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002317 MaybeObject* flat = TryFlatten(pretenure);
2318 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002319 if (!flat->ToObject(&successfully_flattened)) return this;
2320 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002321}
2322
2323
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002324uint16_t String::Get(int index) {
2325 ASSERT(index >= 0 && index < length());
2326 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002327 case kSeqStringTag | kAsciiStringTag:
2328 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2329 case kSeqStringTag | kTwoByteStringTag:
2330 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2331 case kConsStringTag | kAsciiStringTag:
2332 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002333 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002334 case kExternalStringTag | kAsciiStringTag:
2335 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2336 case kExternalStringTag | kTwoByteStringTag:
2337 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002338 case kSlicedStringTag | kAsciiStringTag:
2339 case kSlicedStringTag | kTwoByteStringTag:
2340 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002341 default:
2342 break;
2343 }
2344
2345 UNREACHABLE();
2346 return 0;
2347}
2348
2349
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002350void String::Set(int index, uint16_t value) {
2351 ASSERT(index >= 0 && index < length());
2352 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002353
ager@chromium.org5ec48922009-05-05 07:25:34 +00002354 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002355 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2356 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002357}
2358
2359
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002360bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002361 if (!StringShape(this).IsCons()) return true;
2362 return ConsString::cast(this)->second()->length() == 0;
2363}
2364
2365
2366String* String::GetUnderlying() {
2367 // Giving direct access to underlying string only makes sense if the
2368 // wrapping string is already flattened.
2369 ASSERT(this->IsFlat());
2370 ASSERT(StringShape(this).IsIndirect());
2371 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2372 const int kUnderlyingOffset = SlicedString::kParentOffset;
2373 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002374}
2375
2376
ager@chromium.org7c537e22008-10-16 08:43:32 +00002377uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002378 ASSERT(index >= 0 && index < length());
2379 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2380}
2381
2382
ager@chromium.org7c537e22008-10-16 08:43:32 +00002383void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002384 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2385 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2386 static_cast<byte>(value));
2387}
2388
2389
ager@chromium.org7c537e22008-10-16 08:43:32 +00002390Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002391 return FIELD_ADDR(this, kHeaderSize);
2392}
2393
2394
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002395char* SeqAsciiString::GetChars() {
2396 return reinterpret_cast<char*>(GetCharsAddress());
2397}
2398
2399
ager@chromium.org7c537e22008-10-16 08:43:32 +00002400Address SeqTwoByteString::GetCharsAddress() {
2401 return FIELD_ADDR(this, kHeaderSize);
2402}
2403
2404
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002405uc16* SeqTwoByteString::GetChars() {
2406 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2407}
2408
2409
ager@chromium.org7c537e22008-10-16 08:43:32 +00002410uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002411 ASSERT(index >= 0 && index < length());
2412 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2413}
2414
2415
ager@chromium.org7c537e22008-10-16 08:43:32 +00002416void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002417 ASSERT(index >= 0 && index < length());
2418 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2419}
2420
2421
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002422int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002423 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002424}
2425
2426
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002427int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002428 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002429}
2430
2431
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002432String* SlicedString::parent() {
2433 return String::cast(READ_FIELD(this, kParentOffset));
2434}
2435
2436
2437void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002438 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002439 WRITE_FIELD(this, kParentOffset, parent);
2440}
2441
2442
2443SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2444
2445
ager@chromium.org870a0b62008-11-04 11:43:05 +00002446String* ConsString::first() {
2447 return String::cast(READ_FIELD(this, kFirstOffset));
2448}
2449
2450
2451Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002452 return READ_FIELD(this, kFirstOffset);
2453}
2454
2455
ager@chromium.org870a0b62008-11-04 11:43:05 +00002456void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002457 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002458 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002459}
2460
2461
ager@chromium.org870a0b62008-11-04 11:43:05 +00002462String* ConsString::second() {
2463 return String::cast(READ_FIELD(this, kSecondOffset));
2464}
2465
2466
2467Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002468 return READ_FIELD(this, kSecondOffset);
2469}
2470
2471
ager@chromium.org870a0b62008-11-04 11:43:05 +00002472void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002473 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002474 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002475}
2476
2477
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002478bool ExternalString::is_short() {
2479 InstanceType type = map()->instance_type();
2480 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002481}
2482
2483
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002484const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002485 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2486}
2487
2488
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002489void ExternalAsciiString::update_data_cache() {
2490 if (is_short()) return;
2491 const char** data_field =
2492 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2493 *data_field = resource()->data();
2494}
2495
2496
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002497void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002498 const ExternalAsciiString::Resource* resource) {
2499 *reinterpret_cast<const Resource**>(
2500 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002501 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002502}
2503
2504
2505const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002506 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002507}
2508
2509
2510uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2511 ASSERT(index >= 0 && index < length());
2512 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002513}
2514
2515
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002516const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002517 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2518}
2519
2520
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002521void ExternalTwoByteString::update_data_cache() {
2522 if (is_short()) return;
2523 const uint16_t** data_field =
2524 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2525 *data_field = resource()->data();
2526}
2527
2528
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002529void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002530 const ExternalTwoByteString::Resource* resource) {
2531 *reinterpret_cast<const Resource**>(
2532 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002533 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002534}
2535
2536
2537const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002538 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002539}
2540
2541
2542uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2543 ASSERT(index >= 0 && index < length());
2544 return GetChars()[index];
2545}
2546
2547
2548const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2549 unsigned start) {
2550 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002551}
2552
2553
ager@chromium.orgac091b72010-05-05 07:34:42 +00002554void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002555 set_finger_index(kEntriesIndex);
2556 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002557}
2558
2559
2560void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002561 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002562 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002563 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002564 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002565 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002566 MakeZeroSize();
2567}
2568
2569
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002570int JSFunctionResultCache::size() {
2571 return Smi::cast(get(kCacheSizeIndex))->value();
2572}
2573
2574
2575void JSFunctionResultCache::set_size(int size) {
2576 set(kCacheSizeIndex, Smi::FromInt(size));
2577}
2578
2579
2580int JSFunctionResultCache::finger_index() {
2581 return Smi::cast(get(kFingerIndex))->value();
2582}
2583
2584
2585void JSFunctionResultCache::set_finger_index(int finger_index) {
2586 set(kFingerIndex, Smi::FromInt(finger_index));
2587}
2588
2589
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002590byte ByteArray::get(int index) {
2591 ASSERT(index >= 0 && index < this->length());
2592 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2593}
2594
2595
2596void ByteArray::set(int index, byte value) {
2597 ASSERT(index >= 0 && index < this->length());
2598 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2599}
2600
2601
2602int ByteArray::get_int(int index) {
2603 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2604 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2605}
2606
2607
2608ByteArray* ByteArray::FromDataStartAddress(Address address) {
2609 ASSERT_TAG_ALIGNED(address);
2610 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2611}
2612
2613
2614Address ByteArray::GetDataStartAddress() {
2615 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2616}
2617
2618
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002619uint8_t* ExternalPixelArray::external_pixel_pointer() {
2620 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002621}
2622
2623
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002624uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002625 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002626 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002627 return ptr[index];
2628}
2629
2630
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002631MaybeObject* ExternalPixelArray::get(int index) {
2632 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2633}
2634
2635
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002636void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002637 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002638 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002639 ptr[index] = value;
2640}
2641
2642
ager@chromium.org3811b432009-10-28 14:53:37 +00002643void* ExternalArray::external_pointer() {
2644 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2645 return reinterpret_cast<void*>(ptr);
2646}
2647
2648
2649void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2650 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2651 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2652}
2653
2654
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002655int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002656 ASSERT((index >= 0) && (index < this->length()));
2657 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2658 return ptr[index];
2659}
2660
2661
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002662MaybeObject* ExternalByteArray::get(int index) {
2663 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2664}
2665
2666
ager@chromium.org3811b432009-10-28 14:53:37 +00002667void ExternalByteArray::set(int index, int8_t value) {
2668 ASSERT((index >= 0) && (index < this->length()));
2669 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2670 ptr[index] = value;
2671}
2672
2673
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002674uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002675 ASSERT((index >= 0) && (index < this->length()));
2676 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2677 return ptr[index];
2678}
2679
2680
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002681MaybeObject* ExternalUnsignedByteArray::get(int index) {
2682 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2683}
2684
2685
ager@chromium.org3811b432009-10-28 14:53:37 +00002686void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2687 ASSERT((index >= 0) && (index < this->length()));
2688 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2689 ptr[index] = value;
2690}
2691
2692
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002693int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002694 ASSERT((index >= 0) && (index < this->length()));
2695 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2696 return ptr[index];
2697}
2698
2699
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002700MaybeObject* ExternalShortArray::get(int index) {
2701 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2702}
2703
2704
ager@chromium.org3811b432009-10-28 14:53:37 +00002705void ExternalShortArray::set(int index, int16_t value) {
2706 ASSERT((index >= 0) && (index < this->length()));
2707 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2708 ptr[index] = value;
2709}
2710
2711
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002712uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002713 ASSERT((index >= 0) && (index < this->length()));
2714 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2715 return ptr[index];
2716}
2717
2718
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002719MaybeObject* ExternalUnsignedShortArray::get(int index) {
2720 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2721}
2722
2723
ager@chromium.org3811b432009-10-28 14:53:37 +00002724void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2725 ASSERT((index >= 0) && (index < this->length()));
2726 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2727 ptr[index] = value;
2728}
2729
2730
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002731int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002732 ASSERT((index >= 0) && (index < this->length()));
2733 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2734 return ptr[index];
2735}
2736
2737
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002738MaybeObject* ExternalIntArray::get(int index) {
2739 return GetHeap()->NumberFromInt32(get_scalar(index));
2740}
2741
2742
ager@chromium.org3811b432009-10-28 14:53:37 +00002743void ExternalIntArray::set(int index, int32_t value) {
2744 ASSERT((index >= 0) && (index < this->length()));
2745 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2746 ptr[index] = value;
2747}
2748
2749
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002750uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002751 ASSERT((index >= 0) && (index < this->length()));
2752 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2753 return ptr[index];
2754}
2755
2756
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002757MaybeObject* ExternalUnsignedIntArray::get(int index) {
2758 return GetHeap()->NumberFromUint32(get_scalar(index));
2759}
2760
2761
ager@chromium.org3811b432009-10-28 14:53:37 +00002762void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2763 ASSERT((index >= 0) && (index < this->length()));
2764 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2765 ptr[index] = value;
2766}
2767
2768
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002769float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002770 ASSERT((index >= 0) && (index < this->length()));
2771 float* ptr = static_cast<float*>(external_pointer());
2772 return ptr[index];
2773}
2774
2775
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002776MaybeObject* ExternalFloatArray::get(int index) {
2777 return GetHeap()->NumberFromDouble(get_scalar(index));
2778}
2779
2780
ager@chromium.org3811b432009-10-28 14:53:37 +00002781void ExternalFloatArray::set(int index, float value) {
2782 ASSERT((index >= 0) && (index < this->length()));
2783 float* ptr = static_cast<float*>(external_pointer());
2784 ptr[index] = value;
2785}
2786
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002787
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002788double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002789 ASSERT((index >= 0) && (index < this->length()));
2790 double* ptr = static_cast<double*>(external_pointer());
2791 return ptr[index];
2792}
2793
2794
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002795MaybeObject* ExternalDoubleArray::get(int index) {
2796 return GetHeap()->NumberFromDouble(get_scalar(index));
2797}
2798
2799
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002800void ExternalDoubleArray::set(int index, double value) {
2801 ASSERT((index >= 0) && (index < this->length()));
2802 double* ptr = static_cast<double*>(external_pointer());
2803 ptr[index] = value;
2804}
2805
2806
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002807int Map::visitor_id() {
2808 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2809}
2810
2811
2812void Map::set_visitor_id(int id) {
2813 ASSERT(0 <= id && id < 256);
2814 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2815}
2816
ager@chromium.org3811b432009-10-28 14:53:37 +00002817
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002818int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002819 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2820}
2821
2822
2823int Map::inobject_properties() {
2824 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002825}
2826
2827
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002828int Map::pre_allocated_property_fields() {
2829 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2830}
2831
2832
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002833int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002834 int instance_size = map->instance_size();
2835 if (instance_size != kVariableSizeSentinel) return instance_size;
2836 // We can ignore the "symbol" bit becase it is only set for symbols
2837 // and implies a string type.
2838 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002839 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002840 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002841 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002842 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002843 if (instance_type == ASCII_STRING_TYPE) {
2844 return SeqAsciiString::SizeFor(
2845 reinterpret_cast<SeqAsciiString*>(this)->length());
2846 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002847 if (instance_type == BYTE_ARRAY_TYPE) {
2848 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2849 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002850 if (instance_type == FREE_SPACE_TYPE) {
2851 return reinterpret_cast<FreeSpace*>(this)->size();
2852 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002853 if (instance_type == STRING_TYPE) {
2854 return SeqTwoByteString::SizeFor(
2855 reinterpret_cast<SeqTwoByteString*>(this)->length());
2856 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002857 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2858 return FixedDoubleArray::SizeFor(
2859 reinterpret_cast<FixedDoubleArray*>(this)->length());
2860 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002861 ASSERT(instance_type == CODE_TYPE);
2862 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002863}
2864
2865
2866void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002867 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002868 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002869 ASSERT(0 <= value && value < 256);
2870 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2871}
2872
2873
ager@chromium.org7c537e22008-10-16 08:43:32 +00002874void Map::set_inobject_properties(int value) {
2875 ASSERT(0 <= value && value < 256);
2876 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2877}
2878
2879
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002880void Map::set_pre_allocated_property_fields(int value) {
2881 ASSERT(0 <= value && value < 256);
2882 WRITE_BYTE_FIELD(this,
2883 kPreAllocatedPropertyFieldsOffset,
2884 static_cast<byte>(value));
2885}
2886
2887
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002888InstanceType Map::instance_type() {
2889 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2890}
2891
2892
2893void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002894 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2895}
2896
2897
2898int Map::unused_property_fields() {
2899 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2900}
2901
2902
2903void Map::set_unused_property_fields(int value) {
2904 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2905}
2906
2907
2908byte Map::bit_field() {
2909 return READ_BYTE_FIELD(this, kBitFieldOffset);
2910}
2911
2912
2913void Map::set_bit_field(byte value) {
2914 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2915}
2916
2917
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002918byte Map::bit_field2() {
2919 return READ_BYTE_FIELD(this, kBitField2Offset);
2920}
2921
2922
2923void Map::set_bit_field2(byte value) {
2924 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2925}
2926
2927
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002928void Map::set_non_instance_prototype(bool value) {
2929 if (value) {
2930 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2931 } else {
2932 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2933 }
2934}
2935
2936
2937bool Map::has_non_instance_prototype() {
2938 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2939}
2940
2941
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002942void Map::set_function_with_prototype(bool value) {
2943 if (value) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002944 set_bit_field3(bit_field3() | (1 << kFunctionWithPrototype));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002945 } else {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002946 set_bit_field3(bit_field3() & ~(1 << kFunctionWithPrototype));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002947 }
2948}
2949
2950
2951bool Map::function_with_prototype() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002952 return ((1 << kFunctionWithPrototype) & bit_field3()) != 0;
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002953}
2954
2955
ager@chromium.org870a0b62008-11-04 11:43:05 +00002956void Map::set_is_access_check_needed(bool access_check_needed) {
2957 if (access_check_needed) {
2958 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2959 } else {
2960 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2961 }
2962}
2963
2964
2965bool Map::is_access_check_needed() {
2966 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2967}
2968
2969
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002970void Map::set_is_extensible(bool value) {
2971 if (value) {
2972 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2973 } else {
2974 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2975 }
2976}
2977
2978bool Map::is_extensible() {
2979 return ((1 << kIsExtensible) & bit_field2()) != 0;
2980}
2981
2982
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002983void Map::set_attached_to_shared_function_info(bool value) {
2984 if (value) {
2985 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2986 } else {
2987 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2988 }
2989}
2990
2991bool Map::attached_to_shared_function_info() {
2992 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2993}
2994
2995
2996void Map::set_is_shared(bool value) {
2997 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002998 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002999 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003000 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003001 }
3002}
3003
3004bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003005 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003006}
3007
3008
3009JSFunction* Map::unchecked_constructor() {
3010 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
3011}
3012
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003013
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003014Code::Flags Code::flags() {
3015 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
3016}
3017
3018
3019void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003020 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003021 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003022 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
3023 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003024 ExtractArgumentsCountFromFlags(flags) >= 0);
3025 WRITE_INT_FIELD(this, kFlagsOffset, flags);
3026}
3027
3028
3029Code::Kind Code::kind() {
3030 return ExtractKindFromFlags(flags());
3031}
3032
3033
kasper.lund7276f142008-07-30 08:49:36 +00003034InlineCacheState Code::ic_state() {
3035 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003036 // Only allow uninitialized or debugger states for non-IC code
3037 // objects. This is used in the debugger to determine whether or not
3038 // a call to code object has been replaced with a debug break call.
3039 ASSERT(is_inline_cache_stub() ||
3040 result == UNINITIALIZED ||
3041 result == DEBUG_BREAK ||
3042 result == DEBUG_PREPARE_STEP_IN);
3043 return result;
3044}
3045
3046
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003047Code::ExtraICState Code::extra_ic_state() {
3048 ASSERT(is_inline_cache_stub());
3049 return ExtractExtraICStateFromFlags(flags());
3050}
3051
3052
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003053Code::StubType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003054 return ExtractTypeFromFlags(flags());
3055}
3056
3057
3058int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003059 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003060 return ExtractArgumentsCountFromFlags(flags());
3061}
3062
3063
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003064int Code::major_key() {
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);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003070 return StubMajorKeyField::decode(
3071 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasper.lund7276f142008-07-30 08:49:36 +00003072}
3073
3074
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003075void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003076 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003077 kind() == UNARY_OP_IC ||
3078 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003079 kind() == COMPARE_IC ||
3080 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00003081 ASSERT(0 <= major && major < 256);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003082 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3083 int updated = StubMajorKeyField::update(previous, major);
3084 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003085}
3086
3087
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003088bool Code::is_pregenerated() {
3089 return kind() == STUB && IsPregeneratedField::decode(flags());
3090}
3091
3092
3093void Code::set_is_pregenerated(bool value) {
3094 ASSERT(kind() == STUB);
3095 Flags f = flags();
3096 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3097 set_flags(f);
3098}
3099
3100
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003101bool Code::optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003102 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003103 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3104}
3105
3106
3107void Code::set_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003108 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003109 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3110}
3111
3112
3113bool Code::has_deoptimization_support() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003114 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003115 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3116 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003117}
3118
3119
3120void Code::set_has_deoptimization_support(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003121 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003122 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3123 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3124 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3125}
3126
3127
3128bool Code::has_debug_break_slots() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003129 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003130 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3131 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3132}
3133
3134
3135void Code::set_has_debug_break_slots(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003136 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003137 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3138 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3139 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003140}
3141
3142
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003143bool Code::is_compiled_optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003144 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003145 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3146 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3147}
3148
3149
3150void Code::set_compiled_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003151 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003152 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3153 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3154 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3155}
3156
3157
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003158int Code::allow_osr_at_loop_nesting_level() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003159 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003160 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3161}
3162
3163
3164void Code::set_allow_osr_at_loop_nesting_level(int level) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003165 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003166 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3167 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3168}
3169
3170
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003171int Code::profiler_ticks() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003172 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003173 return READ_BYTE_FIELD(this, kProfilerTicksOffset);
3174}
3175
3176
3177void Code::set_profiler_ticks(int ticks) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003178 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003179 ASSERT(ticks < 256);
3180 WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
3181}
3182
3183
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003184unsigned Code::stack_slots() {
3185 ASSERT(kind() == OPTIMIZED_FUNCTION);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003186 return StackSlotsField::decode(
3187 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003188}
3189
3190
3191void Code::set_stack_slots(unsigned slots) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003192 CHECK(slots <= (1 << kStackSlotsBitCount));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003193 ASSERT(kind() == OPTIMIZED_FUNCTION);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003194 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3195 int updated = StackSlotsField::update(previous, slots);
3196 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003197}
3198
3199
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003200unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003201 ASSERT(kind() == OPTIMIZED_FUNCTION);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003202 return SafepointTableOffsetField::decode(
3203 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003204}
3205
3206
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003207void Code::set_safepoint_table_offset(unsigned offset) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003208 CHECK(offset <= (1 << kSafepointTableOffsetBitCount));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003209 ASSERT(kind() == OPTIMIZED_FUNCTION);
3210 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003211 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3212 int updated = SafepointTableOffsetField::update(previous, offset);
3213 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003214}
3215
3216
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003217unsigned Code::stack_check_table_offset() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003218 ASSERT_EQ(FUNCTION, kind());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003219 return StackCheckTableOffsetField::decode(
3220 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003221}
3222
3223
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003224void Code::set_stack_check_table_offset(unsigned offset) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003225 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003226 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003227 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3228 int updated = StackCheckTableOffsetField::update(previous, offset);
3229 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003230}
3231
3232
3233CheckType Code::check_type() {
3234 ASSERT(is_call_stub() || is_keyed_call_stub());
3235 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3236 return static_cast<CheckType>(type);
3237}
3238
3239
3240void Code::set_check_type(CheckType value) {
3241 ASSERT(is_call_stub() || is_keyed_call_stub());
3242 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3243}
3244
3245
danno@chromium.org40cb8782011-05-25 07:58:50 +00003246byte Code::unary_op_type() {
3247 ASSERT(is_unary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003248 return UnaryOpTypeField::decode(
3249 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003250}
3251
3252
danno@chromium.org40cb8782011-05-25 07:58:50 +00003253void Code::set_unary_op_type(byte value) {
3254 ASSERT(is_unary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003255 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3256 int updated = UnaryOpTypeField::update(previous, value);
3257 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003258}
3259
3260
danno@chromium.org40cb8782011-05-25 07:58:50 +00003261byte Code::binary_op_type() {
3262 ASSERT(is_binary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003263 return BinaryOpTypeField::decode(
3264 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003265}
3266
3267
danno@chromium.org40cb8782011-05-25 07:58:50 +00003268void Code::set_binary_op_type(byte value) {
3269 ASSERT(is_binary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003270 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3271 int updated = BinaryOpTypeField::update(previous, value);
3272 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003273}
3274
3275
danno@chromium.org40cb8782011-05-25 07:58:50 +00003276byte Code::binary_op_result_type() {
3277 ASSERT(is_binary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003278 return BinaryOpResultTypeField::decode(
3279 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003280}
3281
3282
danno@chromium.org40cb8782011-05-25 07:58:50 +00003283void Code::set_binary_op_result_type(byte value) {
3284 ASSERT(is_binary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003285 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3286 int updated = BinaryOpResultTypeField::update(previous, value);
3287 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003288}
3289
3290
3291byte Code::compare_state() {
3292 ASSERT(is_compare_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003293 return CompareStateField::decode(
3294 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003295}
3296
3297
3298void Code::set_compare_state(byte value) {
3299 ASSERT(is_compare_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003300 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3301 int updated = CompareStateField::update(previous, value);
3302 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003303}
3304
3305
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003306byte Code::compare_operation() {
3307 ASSERT(is_compare_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003308 return CompareOperationField::decode(
3309 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003310}
3311
3312
3313void Code::set_compare_operation(byte value) {
3314 ASSERT(is_compare_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003315 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3316 int updated = CompareOperationField::update(previous, value);
3317 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003318}
3319
3320
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003321byte Code::to_boolean_state() {
3322 ASSERT(is_to_boolean_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003323 return ToBooleanStateField::decode(
3324 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003325}
3326
3327
3328void Code::set_to_boolean_state(byte value) {
3329 ASSERT(is_to_boolean_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003330 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3331 int updated = ToBooleanStateField::update(previous, value);
3332 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003333}
3334
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003335
3336bool Code::has_function_cache() {
3337 ASSERT(kind() == STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003338 return HasFunctionCacheField::decode(
3339 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003340}
3341
3342
3343void Code::set_has_function_cache(bool flag) {
3344 ASSERT(kind() == STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003345 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3346 int updated = HasFunctionCacheField::update(previous, flag);
3347 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003348}
3349
3350
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003351bool Code::is_inline_cache_stub() {
3352 Kind kind = this->kind();
3353 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3354}
3355
3356
3357Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003358 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003359 ExtraICState extra_ic_state,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003360 StubType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003361 int argc,
3362 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003363 // Extra IC state is only allowed for call IC stubs or for store IC
3364 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003365 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003366 kind == CALL_IC ||
3367 kind == STORE_IC ||
3368 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003369 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003370 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003371 | ICStateField::encode(ic_state)
3372 | TypeField::encode(type)
3373 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003374 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003375 | CacheHolderField::encode(holder);
3376 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003377}
3378
3379
3380Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003381 StubType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003382 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003383 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003384 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003385 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003386}
3387
3388
3389Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003390 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003391}
3392
3393
kasper.lund7276f142008-07-30 08:49:36 +00003394InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003395 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003396}
3397
3398
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003399Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003400 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003401}
3402
3403
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003404Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003405 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003406}
3407
3408
3409int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003410 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003411}
3412
3413
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003414InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003415 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003416}
3417
3418
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003419Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003420 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003421 return static_cast<Flags>(bits);
3422}
3423
3424
ager@chromium.org8bb60582008-12-11 12:02:20 +00003425Code* Code::GetCodeFromTargetAddress(Address address) {
3426 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3427 // GetCodeFromTargetAddress might be called when marking objects during mark
3428 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3429 // Code::cast. Code::cast does not work when the object's map is
3430 // marked.
3431 Code* result = reinterpret_cast<Code*>(code);
3432 return result;
3433}
3434
3435
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003436Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3437 return HeapObject::
3438 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3439}
3440
3441
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003442Object* Map::prototype() {
3443 return READ_FIELD(this, kPrototypeOffset);
3444}
3445
3446
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003447void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003448 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003449 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003450 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003451}
3452
3453
danno@chromium.org40cb8782011-05-25 07:58:50 +00003454DescriptorArray* Map::instance_descriptors() {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003455 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset);
3456 if (!object->IsDescriptorArray()) {
3457 ASSERT(object->IsMap() || object->IsUndefined());
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003458 return GetHeap()->empty_descriptor_array();
danno@chromium.org40cb8782011-05-25 07:58:50 +00003459 } else {
3460 return DescriptorArray::cast(object);
3461 }
3462}
3463
3464
danno@chromium.org40cb8782011-05-25 07:58:50 +00003465void Map::set_instance_descriptors(DescriptorArray* value,
3466 WriteBarrierMode mode) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003467 Heap* heap = GetHeap();
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003468
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003469 if (value == heap->empty_descriptor_array()) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003470 ClearDescriptorArray(heap, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003471 return;
danno@chromium.org40cb8782011-05-25 07:58:50 +00003472 }
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003473
3474 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset);
3475
3476 if (object->IsDescriptorArray()) {
3477 value->set_back_pointer_storage(
3478 DescriptorArray::cast(object)->back_pointer_storage());
3479 } else {
3480 ASSERT(object->IsMap() || object->IsUndefined());
3481 value->set_back_pointer_storage(object);
3482 }
3483
danno@chromium.org40cb8782011-05-25 07:58:50 +00003484 ASSERT(!is_shared());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003485 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003486 CONDITIONAL_WRITE_BARRIER(
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003487 heap, this, kInstanceDescriptorsOrBackPointerOffset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003488}
3489
3490
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003491SMI_ACCESSORS(Map, bit_field3, kBitField3Offset)
danno@chromium.org40cb8782011-05-25 07:58:50 +00003492
3493
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003494void Map::ClearDescriptorArray(Heap* heap, WriteBarrierMode mode) {
3495 Object* back_pointer = GetBackPointer();
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003496#ifdef DEBUG
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003497 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset);
3498 if (object->IsDescriptorArray()) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003499 ZapTransitions();
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003500 } else {
3501 ASSERT(object->IsMap() || object->IsUndefined());
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003502 }
3503#endif
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003504 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, back_pointer);
3505 CONDITIONAL_WRITE_BARRIER(
3506 heap, this, kInstanceDescriptorsOrBackPointerOffset, back_pointer, mode);
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003507}
3508
3509
danno@chromium.org40cb8782011-05-25 07:58:50 +00003510
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003511Object* Map::GetBackPointer() {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003512 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset);
3513 if (object->IsDescriptorArray()) {
3514 return DescriptorArray::cast(object)->back_pointer_storage();
3515 } else {
3516 ASSERT(object->IsMap() || object->IsUndefined());
3517 return object;
3518 }
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003519}
3520
3521
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003522bool Map::HasElementsTransition() {
3523 return HasTransitionArray() && transitions()->HasElementsTransition();
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003524}
3525
3526
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003527bool Map::HasTransitionArray() {
3528 return instance_descriptors()->HasTransitionArray();
3529}
3530
3531
3532Map* Map::elements_transition_map() {
3533 return transitions()->elements_transition();
3534}
3535
3536
3537MaybeObject* Map::AddTransition(String* key, Object* value) {
3538 if (HasTransitionArray()) return transitions()->CopyInsert(key, value);
3539 return TransitionArray::NewWith(key, value);
3540}
3541
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00003542void Map::SetTransition(int transition_index, Object* value) {
3543 transitions()->SetValue(transition_index, value);
3544}
3545
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003546
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003547// If the map is using the empty descriptor array, install a new empty
3548// descriptor array that will contain an elements transition.
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003549static MaybeObject* AllowTransitions(Map* map) {
3550 if (map->instance_descriptors()->MayContainTransitions()) return map;
3551 DescriptorArray* descriptors;
3552 MaybeObject* maybe_descriptors =
3553 DescriptorArray::Allocate(0, DescriptorArray::CANNOT_BE_SHARED);
3554 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
3555 map->set_instance_descriptors(descriptors);
3556 return descriptors;
3557}
3558
3559
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003560// If the descriptor is using the empty transition array, install a new empty
3561// transition array that will have place for an element transition.
3562static MaybeObject* EnsureHasTransitionArray(Map* map) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003563 if (map->HasTransitionArray()) return map;
3564
3565 AllowTransitions(map);
3566
3567 TransitionArray* transitions;
3568 MaybeObject* maybe_transitions = TransitionArray::Allocate(0);
3569 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
3570 MaybeObject* added_transitions = map->set_transitions(transitions);
3571 if (added_transitions->IsFailure()) return added_transitions;
3572 return transitions;
3573}
3574
3575
3576MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003577 MaybeObject* allow_elements = EnsureHasTransitionArray(this);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003578 if (allow_elements->IsFailure()) return allow_elements;
3579 transitions()->set_elements_transition(transitioned_map);
3580 return this;
3581}
3582
3583
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003584FixedArray* Map::GetPrototypeTransitions() {
3585 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
3586 if (!transitions()->HasPrototypeTransitions()) {
3587 return GetHeap()->empty_fixed_array();
3588 }
3589 return transitions()->GetPrototypeTransitions();
3590}
3591
3592
3593MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
3594 MaybeObject* allow_prototype = EnsureHasTransitionArray(this);
3595 if (allow_prototype->IsFailure()) return allow_prototype;
3596#ifdef DEBUG
3597 if (HasPrototypeTransitions()) {
3598 ASSERT(GetPrototypeTransitions() != proto_transitions);
3599 ZapPrototypeTransitions();
3600 }
3601#endif
3602 transitions()->SetPrototypeTransitions(proto_transitions);
3603 return this;
3604}
3605
3606
3607bool Map::HasPrototypeTransitions() {
3608 return HasTransitionArray() && transitions()->HasPrototypeTransitions();
3609}
3610
3611
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003612TransitionArray* Map::transitions() {
3613 return instance_descriptors()->transitions();
3614}
3615
3616
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003617void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003618#ifdef DEBUG
3619 ZapTransitions();
3620#endif
3621 DescriptorArray* descriptors = instance_descriptors();
3622 if (descriptors->number_of_descriptors() == 0) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003623 ClearDescriptorArray(heap, mode);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003624 } else {
3625 descriptors->ClearTransitions();
3626 }
3627}
3628
3629
3630MaybeObject* Map::set_transitions(TransitionArray* transitions_array) {
3631 MaybeObject* allow_transitions = AllowTransitions(this);
3632 if (allow_transitions->IsFailure()) return allow_transitions;
3633#ifdef DEBUG
3634 if (HasTransitionArray()) {
3635 ASSERT(transitions() != transitions_array);
3636 ZapTransitions();
3637 }
3638#endif
3639 instance_descriptors()->set_transitions(transitions_array);
3640 return this;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003641}
3642
3643
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003644void Map::init_back_pointer(Object* undefined) {
3645 ASSERT(undefined->IsUndefined());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003646 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, undefined);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003647}
3648
3649
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003650void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003651 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
3652 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
3653 (value->IsMap() && GetBackPointer()->IsUndefined()));
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003654 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset);
3655 if (object->IsMap()) {
3656 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, value);
3657 CONDITIONAL_WRITE_BARRIER(
3658 GetHeap(), this, kInstanceDescriptorsOrBackPointerOffset, value, mode);
3659 } else {
3660 DescriptorArray::cast(object)->set_back_pointer_storage(value);
3661 }
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003662}
3663
3664
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003665// Can either be Smi (no transitions), normal transition array, or a transition
3666// array with the header overwritten as a Smi (thus iterating).
3667TransitionArray* Map::unchecked_transition_array() {
3668 ASSERT(HasTransitionArray());
3669 Object* object = *HeapObject::RawField(instance_descriptors(),
3670 DescriptorArray::kTransitionsOffset);
3671 ASSERT(!object->IsSmi());
3672 TransitionArray* transition_array = static_cast<TransitionArray*>(object);
3673 return transition_array;
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003674}
3675
3676
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003677HeapObject* Map::UncheckedPrototypeTransitions() {
3678 ASSERT(HasTransitionArray());
3679 ASSERT(unchecked_transition_array()->HasPrototypeTransitions());
3680 return unchecked_transition_array()->UncheckedPrototypeTransitions();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003681}
3682
3683
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003684ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003685ACCESSORS(Map, constructor, Object, kConstructorOffset)
3686
3687ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003688ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003689ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003690
3691ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3692ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003693ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003694
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003695ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003696
3697ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3698ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3699ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3700ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003701ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003702ACCESSORS(AccessorInfo, expected_receiver_type, Object,
3703 kExpectedReceiverTypeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003704
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003705ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3706ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3707
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003708ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3709ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3710ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3711
3712ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3713ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3714ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3715ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3716ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3717ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3718
3719ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3720ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3721
3722ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3723ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3724
3725ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3726ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003727ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3728 kPropertyAccessorsOffset)
3729ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3730 kPrototypeTemplateOffset)
3731ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3732ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3733 kNamedPropertyHandlerOffset)
3734ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3735 kIndexedPropertyHandlerOffset)
3736ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3737 kInstanceTemplateOffset)
3738ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3739ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003740ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3741 kInstanceCallHandlerOffset)
3742ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3743 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003744ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003745
3746ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003747ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3748 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003749
3750ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3751ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3752
3753ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3754
3755ACCESSORS(Script, source, Object, kSourceOffset)
3756ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003757ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003758ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
3759ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003760ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003761ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003762ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003763ACCESSORS_TO_SMI(Script, type, kTypeOffset)
3764ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
3765ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003766ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003767ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003768ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
3769 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003770
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003771#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003772ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3773ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3774ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3775ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3776
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003777ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
3778ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
3779ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003780ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003781#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003782
3783ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003784ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
3785 kOptimizedCodeMapOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003786ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3787ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003788ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3789 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003790ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003791ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3792ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003793ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003794ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3795 kThisPropertyAssignmentsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003796SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003797
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00003798
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003799BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3800 kHiddenPrototypeBit)
3801BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3802BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3803 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003804BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3805 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003806BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3807 kIsExpressionBit)
3808BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3809 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003810BOOL_GETTER(SharedFunctionInfo,
3811 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003812 has_only_simple_this_property_assignments,
3813 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003814BOOL_ACCESSORS(SharedFunctionInfo,
3815 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003816 allows_lazy_compilation,
3817 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003818BOOL_ACCESSORS(SharedFunctionInfo,
3819 compiler_hints,
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003820 allows_lazy_compilation_without_context,
3821 kAllowLazyCompilationWithoutContext)
3822BOOL_ACCESSORS(SharedFunctionInfo,
3823 compiler_hints,
whesse@chromium.org7b260152011-06-20 15:33:18 +00003824 uses_arguments,
3825 kUsesArguments)
3826BOOL_ACCESSORS(SharedFunctionInfo,
3827 compiler_hints,
3828 has_duplicate_parameters,
3829 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003830
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003831
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003832#if V8_HOST_ARCH_32_BIT
3833SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3834SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003835 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003836SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003837 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003838SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3839SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003840 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003841SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3842SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003843 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003844SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003845 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003846SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003847 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003848SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003849SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
3850SMI_ACCESSORS(SharedFunctionInfo,
3851 stress_deopt_counter,
3852 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003853#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003854
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003855#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003856 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003857 int holder::name() { \
3858 int value = READ_INT_FIELD(this, offset); \
3859 ASSERT(kHeapObjectTag == 1); \
3860 ASSERT((value & kHeapObjectTag) == 0); \
3861 return value >> 1; \
3862 } \
3863 void holder::set_##name(int value) { \
3864 ASSERT(kHeapObjectTag == 1); \
3865 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3866 (value & 0xC0000000) == 0x000000000); \
3867 WRITE_INT_FIELD(this, \
3868 offset, \
3869 (value << 1) & ~kHeapObjectTag); \
3870 }
3871
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003872#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3873 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003874 INT_ACCESSORS(holder, name, offset)
3875
3876
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003877PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003878PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3879 formal_parameter_count,
3880 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003881
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003882PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3883 expected_nof_properties,
3884 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003885PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3886
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003887PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3888PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3889 start_position_and_type,
3890 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003891
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003892PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3893 function_token_position,
3894 kFunctionTokenPositionOffset)
3895PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3896 compiler_hints,
3897 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003898
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003899PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3900 this_property_assignments_count,
3901 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003902PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003903
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003904PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, counters, kCountersOffset)
3905PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3906 stress_deopt_counter,
3907 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003908#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003909
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003910
3911int SharedFunctionInfo::construction_count() {
3912 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3913}
3914
3915
3916void SharedFunctionInfo::set_construction_count(int value) {
3917 ASSERT(0 <= value && value < 256);
3918 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3919}
3920
3921
whesse@chromium.org7b260152011-06-20 15:33:18 +00003922BOOL_ACCESSORS(SharedFunctionInfo,
3923 compiler_hints,
3924 live_objects_may_exist,
3925 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003926
3927
3928bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003929 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003930}
3931
3932
whesse@chromium.org7b260152011-06-20 15:33:18 +00003933BOOL_GETTER(SharedFunctionInfo,
3934 compiler_hints,
3935 optimization_disabled,
3936 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003937
3938
3939void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3940 set_compiler_hints(BooleanBit::set(compiler_hints(),
3941 kOptimizationDisabled,
3942 disable));
3943 // If disabling optimizations we reflect that in the code object so
3944 // it will not be counted as optimizable code.
3945 if ((code()->kind() == Code::FUNCTION) && disable) {
3946 code()->set_optimizable(false);
3947 }
3948}
3949
3950
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003951int SharedFunctionInfo::profiler_ticks() {
3952 if (code()->kind() != Code::FUNCTION) return 0;
3953 return code()->profiler_ticks();
3954}
3955
3956
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003957LanguageMode SharedFunctionInfo::language_mode() {
3958 int hints = compiler_hints();
3959 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3960 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3961 return EXTENDED_MODE;
3962 }
3963 return BooleanBit::get(hints, kStrictModeFunction)
3964 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003965}
3966
3967
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003968void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3969 // We only allow language mode transitions that go set the same language mode
3970 // again or go up in the chain:
3971 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3972 ASSERT(this->language_mode() == CLASSIC_MODE ||
3973 this->language_mode() == language_mode ||
3974 language_mode == EXTENDED_MODE);
3975 int hints = compiler_hints();
3976 hints = BooleanBit::set(
3977 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3978 hints = BooleanBit::set(
3979 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3980 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003981}
3982
3983
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003984bool SharedFunctionInfo::is_classic_mode() {
3985 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3986}
3987
3988BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3989 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003990BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3991BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3992 name_should_print_as_anonymous,
3993 kNameShouldPrintAsAnonymous)
3994BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3995BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00003996BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
3997BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
3998 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003999BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004000BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_cache, kDontCache)
whesse@chromium.org7b260152011-06-20 15:33:18 +00004001
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004002void SharedFunctionInfo::BeforeVisitingPointers() {
4003 if (IsInobjectSlackTrackingInProgress()) DetachInitialMap();
4004
4005 // Flush optimized code map on major GC.
4006 // Note: we may experiment with rebuilding it or retaining entries
4007 // which should survive as we iterate through optimized functions
4008 // anyway.
4009 set_optimized_code_map(Smi::FromInt(0));
4010}
4011
4012
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004013ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
4014ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
4015
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00004016ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
4017
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00004018bool Script::HasValidSource() {
4019 Object* src = this->source();
4020 if (!src->IsString()) return true;
4021 String* src_str = String::cast(src);
4022 if (!StringShape(src_str).IsExternal()) return true;
4023 if (src_str->IsAsciiRepresentation()) {
4024 return ExternalAsciiString::cast(src)->resource() != NULL;
4025 } else if (src_str->IsTwoByteRepresentation()) {
4026 return ExternalTwoByteString::cast(src)->resource() != NULL;
4027 }
4028 return true;
4029}
4030
4031
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00004032void SharedFunctionInfo::DontAdaptArguments() {
4033 ASSERT(code()->kind() == Code::BUILTIN);
4034 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
4035}
4036
4037
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004038int SharedFunctionInfo::start_position() {
4039 return start_position_and_type() >> kStartPositionShift;
4040}
4041
4042
4043void SharedFunctionInfo::set_start_position(int start_position) {
4044 set_start_position_and_type((start_position << kStartPositionShift)
4045 | (start_position_and_type() & ~kStartPositionMask));
4046}
4047
4048
4049Code* SharedFunctionInfo::code() {
4050 return Code::cast(READ_FIELD(this, kCodeOffset));
4051}
4052
4053
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004054Code* SharedFunctionInfo::unchecked_code() {
4055 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
4056}
4057
4058
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004059void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004060 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004061 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004062}
4063
4064
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004065ScopeInfo* SharedFunctionInfo::scope_info() {
4066 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00004067}
4068
4069
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004070void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00004071 WriteBarrierMode mode) {
4072 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004073 CONDITIONAL_WRITE_BARRIER(GetHeap(),
4074 this,
4075 kScopeInfoOffset,
4076 reinterpret_cast<Object*>(value),
4077 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00004078}
4079
4080
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004081bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004082 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004083 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004084}
4085
4086
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004087bool SharedFunctionInfo::IsApiFunction() {
4088 return function_data()->IsFunctionTemplateInfo();
4089}
4090
4091
4092FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
4093 ASSERT(IsApiFunction());
4094 return FunctionTemplateInfo::cast(function_data());
4095}
4096
4097
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004098bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00004099 return function_data()->IsSmi();
4100}
4101
4102
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004103BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
4104 ASSERT(HasBuiltinFunctionId());
4105 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004106}
4107
4108
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004109int SharedFunctionInfo::code_age() {
4110 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
4111}
4112
4113
4114void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00004115 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
4116 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004117}
4118
4119
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004120int SharedFunctionInfo::ic_age() {
4121 return ICAgeBits::decode(counters());
4122}
4123
4124
4125void SharedFunctionInfo::set_ic_age(int ic_age) {
4126 set_counters(ICAgeBits::update(counters(), ic_age));
4127}
4128
4129
4130int SharedFunctionInfo::deopt_count() {
4131 return DeoptCountBits::decode(counters());
4132}
4133
4134
4135void SharedFunctionInfo::set_deopt_count(int deopt_count) {
4136 set_counters(DeoptCountBits::update(counters(), deopt_count));
4137}
4138
4139
4140void SharedFunctionInfo::increment_deopt_count() {
4141 int value = counters();
4142 int deopt_count = DeoptCountBits::decode(value);
4143 deopt_count = (deopt_count + 1) & DeoptCountBits::kMax;
4144 set_counters(DeoptCountBits::update(value, deopt_count));
4145}
4146
4147
4148int SharedFunctionInfo::opt_reenable_tries() {
4149 return OptReenableTriesBits::decode(counters());
4150}
4151
4152
4153void SharedFunctionInfo::set_opt_reenable_tries(int tries) {
4154 set_counters(OptReenableTriesBits::update(counters(), tries));
4155}
4156
4157
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004158bool SharedFunctionInfo::has_deoptimization_support() {
4159 Code* code = this->code();
4160 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
4161}
4162
4163
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004164void SharedFunctionInfo::TryReenableOptimization() {
4165 int tries = opt_reenable_tries();
4166 set_opt_reenable_tries((tries + 1) & OptReenableTriesBits::kMax);
4167 // We reenable optimization whenever the number of tries is a large
4168 // enough power of 2.
4169 if (tries >= 16 && (((tries - 1) & tries) == 0)) {
4170 set_optimization_disabled(false);
4171 set_opt_count(0);
4172 set_deopt_count(0);
4173 code()->set_optimizable(true);
4174 }
4175}
4176
4177
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004178bool JSFunction::IsBuiltin() {
4179 return context()->global()->IsJSBuiltinsObject();
4180}
4181
4182
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004183bool JSFunction::NeedsArgumentsAdaption() {
4184 return shared()->formal_parameter_count() !=
4185 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
4186}
4187
4188
4189bool JSFunction::IsOptimized() {
4190 return code()->kind() == Code::OPTIMIZED_FUNCTION;
4191}
4192
4193
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00004194bool JSFunction::IsOptimizable() {
4195 return code()->kind() == Code::FUNCTION && code()->optimizable();
4196}
4197
4198
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004199bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004200 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004201}
4202
4203
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004204Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004205 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004206}
4207
4208
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004209Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004210 return reinterpret_cast<Code*>(
4211 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004212}
4213
4214
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004215void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004216 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004217 Address entry = value->entry();
4218 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004219 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
4220 this,
4221 HeapObject::RawField(this, kCodeEntryOffset),
4222 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004223}
4224
4225
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004226void JSFunction::ReplaceCode(Code* code) {
4227 bool was_optimized = IsOptimized();
4228 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
4229
4230 set_code(code);
4231
4232 // Add/remove the function from the list of optimized functions for this
4233 // context based on the state change.
4234 if (!was_optimized && is_optimized) {
4235 context()->global_context()->AddOptimizedFunction(this);
4236 }
4237 if (was_optimized && !is_optimized) {
4238 context()->global_context()->RemoveOptimizedFunction(this);
4239 }
4240}
4241
4242
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004243Context* JSFunction::context() {
4244 return Context::cast(READ_FIELD(this, kContextOffset));
4245}
4246
4247
4248Object* JSFunction::unchecked_context() {
4249 return READ_FIELD(this, kContextOffset);
4250}
4251
4252
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004253SharedFunctionInfo* JSFunction::unchecked_shared() {
4254 return reinterpret_cast<SharedFunctionInfo*>(
4255 READ_FIELD(this, kSharedFunctionInfoOffset));
4256}
4257
4258
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004259void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004260 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004261 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004262 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004263}
4264
4265ACCESSORS(JSFunction, prototype_or_initial_map, Object,
4266 kPrototypeOrInitialMapOffset)
4267
4268
4269Map* JSFunction::initial_map() {
4270 return Map::cast(prototype_or_initial_map());
4271}
4272
4273
4274void JSFunction::set_initial_map(Map* value) {
4275 set_prototype_or_initial_map(value);
4276}
4277
4278
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004279MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
4280 Map* initial_map) {
4281 Context* global_context = context()->global_context();
4282 Object* array_function =
4283 global_context->get(Context::ARRAY_FUNCTION_INDEX);
4284 if (array_function->IsJSFunction() &&
4285 this == JSFunction::cast(array_function)) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004286 // Replace all of the cached initial array maps in the global context with
4287 // the appropriate transitioned elements kind maps.
4288 Heap* heap = GetHeap();
4289 MaybeObject* maybe_maps =
4290 heap->AllocateFixedArrayWithHoles(kElementsKindCount);
4291 FixedArray* maps;
4292 if (!maybe_maps->To(&maps)) return maybe_maps;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004293
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004294 Map* current_map = initial_map;
4295 ElementsKind kind = current_map->elements_kind();
4296 ASSERT(kind == GetInitialFastElementsKind());
4297 maps->set(kind, current_map);
4298 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
4299 i < kFastElementsKindCount; ++i) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004300 Map* new_map;
4301 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
4302 MaybeObject* maybe_new_map =
4303 current_map->CreateNextElementsTransition(next_kind);
4304 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
4305 maps->set(next_kind, new_map);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004306 current_map = new_map;
4307 }
4308 global_context->set_js_array_maps(maps);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004309 }
4310 set_initial_map(initial_map);
4311 return this;
4312}
4313
4314
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004315bool JSFunction::has_initial_map() {
4316 return prototype_or_initial_map()->IsMap();
4317}
4318
4319
4320bool JSFunction::has_instance_prototype() {
4321 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4322}
4323
4324
4325bool JSFunction::has_prototype() {
4326 return map()->has_non_instance_prototype() || has_instance_prototype();
4327}
4328
4329
4330Object* JSFunction::instance_prototype() {
4331 ASSERT(has_instance_prototype());
4332 if (has_initial_map()) return initial_map()->prototype();
4333 // When there is no initial map and the prototype is a JSObject, the
4334 // initial map field is used for the prototype field.
4335 return prototype_or_initial_map();
4336}
4337
4338
4339Object* JSFunction::prototype() {
4340 ASSERT(has_prototype());
4341 // If the function's prototype property has been set to a non-JSObject
4342 // value, that value is stored in the constructor field of the map.
4343 if (map()->has_non_instance_prototype()) return map()->constructor();
4344 return instance_prototype();
4345}
4346
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004347
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00004348bool JSFunction::should_have_prototype() {
4349 return map()->function_with_prototype();
4350}
4351
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004352
4353bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004354 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004355}
4356
4357
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004358FixedArray* JSFunction::literals() {
4359 ASSERT(!shared()->bound());
4360 return literals_or_bindings();
4361}
4362
4363
4364void JSFunction::set_literals(FixedArray* literals) {
4365 ASSERT(!shared()->bound());
4366 set_literals_or_bindings(literals);
4367}
4368
4369
4370FixedArray* JSFunction::function_bindings() {
4371 ASSERT(shared()->bound());
4372 return literals_or_bindings();
4373}
4374
4375
4376void JSFunction::set_function_bindings(FixedArray* bindings) {
4377 ASSERT(shared()->bound());
4378 // Bound function literal may be initialized to the empty fixed array
4379 // before the bindings are set.
4380 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4381 bindings->map() == GetHeap()->fixed_cow_array_map());
4382 set_literals_or_bindings(bindings);
4383}
4384
4385
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004386int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004387 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004388 return literals()->length();
4389}
4390
4391
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004392Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004393 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004394 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004395}
4396
4397
4398void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4399 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004400 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004401 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004402 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004403}
4404
4405
4406Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004407 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004408 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4409}
4410
4411
4412void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4413 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004414 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004415 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004416 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004417}
4418
4419
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004420ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004421ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004422ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4423ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4424
4425
4426void JSProxy::InitializeBody(int object_size, Object* value) {
4427 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4428 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4429 WRITE_FIELD(this, offset, value);
4430 }
4431}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004432
4433
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004434ACCESSORS(JSSet, table, Object, kTableOffset)
4435ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004436ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4437ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004438
4439
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004440Address Foreign::foreign_address() {
4441 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004442}
4443
4444
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004445void Foreign::set_foreign_address(Address value) {
4446 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004447}
4448
4449
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004450ACCESSORS(JSModule, context, Object, kContextOffset)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004451ACCESSORS(JSModule, scope_info, ScopeInfo, kScopeInfoOffset)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004452
4453
4454JSModule* JSModule::cast(Object* obj) {
4455 ASSERT(obj->IsJSModule());
4456 ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
4457 return reinterpret_cast<JSModule*>(obj);
4458}
4459
4460
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004461ACCESSORS(JSValue, value, Object, kValueOffset)
4462
4463
4464JSValue* JSValue::cast(Object* obj) {
4465 ASSERT(obj->IsJSValue());
4466 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4467 return reinterpret_cast<JSValue*>(obj);
4468}
4469
4470
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004471ACCESSORS(JSDate, value, Object, kValueOffset)
4472ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4473ACCESSORS(JSDate, year, Object, kYearOffset)
4474ACCESSORS(JSDate, month, Object, kMonthOffset)
4475ACCESSORS(JSDate, day, Object, kDayOffset)
4476ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4477ACCESSORS(JSDate, hour, Object, kHourOffset)
4478ACCESSORS(JSDate, min, Object, kMinOffset)
4479ACCESSORS(JSDate, sec, Object, kSecOffset)
4480
4481
4482JSDate* JSDate::cast(Object* obj) {
4483 ASSERT(obj->IsJSDate());
4484 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4485 return reinterpret_cast<JSDate*>(obj);
4486}
4487
4488
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004489ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4490ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4491ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4492ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4493ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4494SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4495SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4496
4497
4498JSMessageObject* JSMessageObject::cast(Object* obj) {
4499 ASSERT(obj->IsJSMessageObject());
4500 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4501 return reinterpret_cast<JSMessageObject*>(obj);
4502}
4503
4504
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004505INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004506ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004507ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004508ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004509ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004510ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00004511INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004512
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004513byte* Code::instruction_start() {
4514 return FIELD_ADDR(this, kHeaderSize);
4515}
4516
4517
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004518byte* Code::instruction_end() {
4519 return instruction_start() + instruction_size();
4520}
4521
4522
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004523int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004524 return RoundUp(instruction_size(), kObjectAlignment);
4525}
4526
4527
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004528FixedArray* Code::unchecked_deoptimization_data() {
4529 return reinterpret_cast<FixedArray*>(
4530 READ_FIELD(this, kDeoptimizationDataOffset));
4531}
4532
4533
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004534ByteArray* Code::unchecked_relocation_info() {
4535 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004536}
4537
4538
4539byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004540 return unchecked_relocation_info()->GetDataStartAddress();
4541}
4542
4543
4544int Code::relocation_size() {
4545 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004546}
4547
4548
4549byte* Code::entry() {
4550 return instruction_start();
4551}
4552
4553
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004554bool Code::contains(byte* inner_pointer) {
4555 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004556}
4557
4558
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004559ACCESSORS(JSArray, length, Object, kLengthOffset)
4560
4561
ager@chromium.org236ad962008-09-25 09:45:57 +00004562ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004563
4564
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004565JSRegExp::Type JSRegExp::TypeTag() {
4566 Object* data = this->data();
4567 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4568 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4569 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004570}
4571
4572
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004573JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4574 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4575 return static_cast<JSRegExp::Type>(smi->value());
4576}
4577
4578
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004579int JSRegExp::CaptureCount() {
4580 switch (TypeTag()) {
4581 case ATOM:
4582 return 0;
4583 case IRREGEXP:
4584 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4585 default:
4586 UNREACHABLE();
4587 return -1;
4588 }
4589}
4590
4591
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004592JSRegExp::Flags JSRegExp::GetFlags() {
4593 ASSERT(this->data()->IsFixedArray());
4594 Object* data = this->data();
4595 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4596 return Flags(smi->value());
4597}
4598
4599
4600String* JSRegExp::Pattern() {
4601 ASSERT(this->data()->IsFixedArray());
4602 Object* data = this->data();
4603 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4604 return pattern;
4605}
4606
4607
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004608Object* JSRegExp::DataAt(int index) {
4609 ASSERT(TypeTag() != NOT_COMPILED);
4610 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004611}
4612
4613
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004614Object* JSRegExp::DataAtUnchecked(int index) {
4615 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4616 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4617 return READ_FIELD(fa, offset);
4618}
4619
4620
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004621void JSRegExp::SetDataAt(int index, Object* value) {
4622 ASSERT(TypeTag() != NOT_COMPILED);
4623 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4624 FixedArray::cast(data())->set(index, value);
4625}
4626
4627
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004628void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4629 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4630 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4631 if (value->IsSmi()) {
4632 fa->set_unchecked(index, Smi::cast(value));
4633 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004634 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004635 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4636 }
4637}
4638
4639
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004640ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004641 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004642#if DEBUG
4643 FixedArrayBase* fixed_array =
4644 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4645 Map* map = fixed_array->map();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004646 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
4647 (map == GetHeap()->fixed_array_map() ||
4648 map == GetHeap()->fixed_cow_array_map())) ||
4649 (IsFastDoubleElementsKind(kind) &&
4650 (fixed_array->IsFixedDoubleArray() ||
4651 fixed_array == GetHeap()->empty_fixed_array())) ||
4652 (kind == DICTIONARY_ELEMENTS &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004653 fixed_array->IsFixedArray() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004654 fixed_array->IsDictionary()) ||
4655 (kind > DICTIONARY_ELEMENTS));
4656 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4657 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004658#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004659 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004660}
4661
4662
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004663ElementsAccessor* JSObject::GetElementsAccessor() {
4664 return ElementsAccessor::ForKind(GetElementsKind());
4665}
4666
4667
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004668bool JSObject::HasFastObjectElements() {
4669 return IsFastObjectElementsKind(GetElementsKind());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004670}
4671
4672
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004673bool JSObject::HasFastSmiElements() {
4674 return IsFastSmiElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004675}
4676
4677
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004678bool JSObject::HasFastSmiOrObjectElements() {
4679 return IsFastSmiOrObjectElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004680}
4681
4682
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004683bool JSObject::HasFastDoubleElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004684 return IsFastDoubleElementsKind(GetElementsKind());
4685}
4686
4687
4688bool JSObject::HasFastHoleyElements() {
4689 return IsFastHoleyElementsKind(GetElementsKind());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004690}
4691
4692
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004693bool JSObject::HasDictionaryElements() {
4694 return GetElementsKind() == DICTIONARY_ELEMENTS;
4695}
4696
4697
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004698bool JSObject::HasNonStrictArgumentsElements() {
4699 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4700}
4701
4702
ager@chromium.org3811b432009-10-28 14:53:37 +00004703bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004704 HeapObject* array = elements();
4705 ASSERT(array != NULL);
4706 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004707}
4708
4709
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004710#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4711bool JSObject::HasExternal##name##Elements() { \
4712 HeapObject* array = elements(); \
4713 ASSERT(array != NULL); \
4714 if (!array->IsHeapObject()) \
4715 return false; \
4716 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004717}
4718
4719
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004720EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4721EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4722EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4723EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4724 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4725EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4726EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4727 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4728EXTERNAL_ELEMENTS_CHECK(Float,
4729 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004730EXTERNAL_ELEMENTS_CHECK(Double,
4731 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004732EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004733
4734
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004735bool JSObject::HasNamedInterceptor() {
4736 return map()->has_named_interceptor();
4737}
4738
4739
4740bool JSObject::HasIndexedInterceptor() {
4741 return map()->has_indexed_interceptor();
4742}
4743
4744
lrn@chromium.org303ada72010-10-27 09:33:13 +00004745MaybeObject* JSObject::EnsureWritableFastElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004746 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004747 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004748 Isolate* isolate = GetIsolate();
4749 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004750 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004751 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4752 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004753 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4754 return maybe_writable_elems;
4755 }
4756 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004757 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004758 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004759 return writable_elems;
4760}
4761
4762
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004763StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004764 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004765 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004766}
4767
4768
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004769SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004770 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004771 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004772}
4773
4774
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004775bool String::IsHashFieldComputed(uint32_t field) {
4776 return (field & kHashNotComputedMask) == 0;
4777}
4778
4779
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004780bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004781 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004782}
4783
4784
4785uint32_t String::Hash() {
4786 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004787 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004788 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004789 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004790 return ComputeAndSetHash();
4791}
4792
4793
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004794StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004795 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004796 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004797 array_index_(0),
4798 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4799 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004800 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004801 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004802}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004803
4804
4805bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004806 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004807}
4808
4809
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004810void StringHasher::AddCharacter(uint32_t c) {
4811 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4812 AddSurrogatePair(c); // Not inlined.
4813 return;
4814 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004815 // Use the Jenkins one-at-a-time hash function to update the hash
4816 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004817 raw_running_hash_ += c;
4818 raw_running_hash_ += (raw_running_hash_ << 10);
4819 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004820 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004821 if (is_array_index_) {
4822 if (c < '0' || c > '9') {
4823 is_array_index_ = false;
4824 } else {
4825 int d = c - '0';
4826 if (is_first_char_) {
4827 is_first_char_ = false;
4828 if (c == '0' && length_ > 1) {
4829 is_array_index_ = false;
4830 return;
4831 }
4832 }
4833 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4834 is_array_index_ = false;
4835 } else {
4836 array_index_ = array_index_ * 10 + d;
4837 }
4838 }
4839 }
4840}
4841
4842
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004843void StringHasher::AddCharacterNoIndex(uint32_t c) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00004844 ASSERT(!is_array_index());
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004845 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4846 AddSurrogatePairNoIndex(c); // Not inlined.
4847 return;
4848 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004849 raw_running_hash_ += c;
4850 raw_running_hash_ += (raw_running_hash_ << 10);
4851 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4852}
4853
4854
4855uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004856 // Get the calculated raw hash value and do some more bit ops to distribute
4857 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004858 uint32_t result = raw_running_hash_;
4859 result += (result << 3);
4860 result ^= (result >> 11);
4861 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004862 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004863 result = 27;
4864 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004865 return result;
4866}
4867
4868
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004869template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004870uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4871 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004872 if (!hasher.has_trivial_hash()) {
4873 int i;
4874 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4875 hasher.AddCharacter(chars[i]);
4876 }
4877 for (; i < length; i++) {
4878 hasher.AddCharacterNoIndex(chars[i]);
4879 }
4880 }
4881 return hasher.GetHashField();
4882}
4883
4884
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004885bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004886 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004887 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4888 return false;
4889 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004890 return SlowAsArrayIndex(index);
4891}
4892
4893
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004894Object* JSReceiver::GetPrototype() {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004895 return map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004896}
4897
4898
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00004899Object* JSReceiver::GetConstructor() {
4900 return map()->constructor();
4901}
4902
4903
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004904bool JSReceiver::HasProperty(String* name) {
4905 if (IsJSProxy()) {
4906 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4907 }
4908 return GetPropertyAttribute(name) != ABSENT;
4909}
4910
4911
4912bool JSReceiver::HasLocalProperty(String* name) {
4913 if (IsJSProxy()) {
4914 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4915 }
4916 return GetLocalPropertyAttribute(name) != ABSENT;
4917}
4918
4919
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004920PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004921 return GetPropertyAttributeWithReceiver(this, key);
4922}
4923
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004924// TODO(504): this may be useful in other places too where JSGlobalProxy
4925// is used.
4926Object* JSObject::BypassGlobalProxy() {
4927 if (IsJSGlobalProxy()) {
4928 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004929 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004930 ASSERT(proto->IsJSGlobalObject());
4931 return proto;
4932 }
4933 return this;
4934}
4935
4936
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004937MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4938 return IsJSProxy()
4939 ? JSProxy::cast(this)->GetIdentityHash(flag)
4940 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004941}
4942
4943
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004944bool JSReceiver::HasElement(uint32_t index) {
4945 if (IsJSProxy()) {
4946 return JSProxy::cast(this)->HasElementWithHandler(index);
4947 }
4948 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004949}
4950
4951
4952bool AccessorInfo::all_can_read() {
4953 return BooleanBit::get(flag(), kAllCanReadBit);
4954}
4955
4956
4957void AccessorInfo::set_all_can_read(bool value) {
4958 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4959}
4960
4961
4962bool AccessorInfo::all_can_write() {
4963 return BooleanBit::get(flag(), kAllCanWriteBit);
4964}
4965
4966
4967void AccessorInfo::set_all_can_write(bool value) {
4968 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4969}
4970
4971
ager@chromium.org870a0b62008-11-04 11:43:05 +00004972bool AccessorInfo::prohibits_overwriting() {
4973 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4974}
4975
4976
4977void AccessorInfo::set_prohibits_overwriting(bool value) {
4978 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4979}
4980
4981
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004982PropertyAttributes AccessorInfo::property_attributes() {
4983 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4984}
4985
4986
4987void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004988 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004989}
4990
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004991
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004992bool AccessorInfo::IsCompatibleReceiver(Object* receiver) {
4993 Object* function_template = expected_receiver_type();
4994 if (!function_template->IsFunctionTemplateInfo()) return true;
4995 return receiver->IsInstanceOf(FunctionTemplateInfo::cast(function_template));
4996}
4997
4998
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004999template<typename Shape, typename Key>
5000void Dictionary<Shape, Key>::SetEntry(int entry,
5001 Object* key,
5002 Object* value) {
5003 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
5004}
5005
5006
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005007template<typename Shape, typename Key>
5008void Dictionary<Shape, Key>::SetEntry(int entry,
5009 Object* key,
5010 Object* value,
5011 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00005012 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005013 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005014 AssertNoAllocation no_gc;
5015 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005016 FixedArray::set(index, key, mode);
5017 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005018 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005019}
5020
5021
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005022bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
5023 ASSERT(other->IsNumber());
5024 return key == static_cast<uint32_t>(other->Number());
5025}
5026
5027
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005028uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
5029 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005030}
5031
5032
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005033uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
5034 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005035 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005036 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005037}
5038
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005039uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
5040 return ComputeIntegerHash(key, seed);
5041}
5042
5043uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
5044 uint32_t seed,
5045 Object* other) {
5046 ASSERT(other->IsNumber());
5047 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
5048}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005049
5050MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
5051 return Isolate::Current()->heap()->NumberFromUint32(key);
5052}
5053
5054
5055bool StringDictionaryShape::IsMatch(String* key, Object* other) {
5056 // We know that all entries in a hash table had their hash keys created.
5057 // Use that knowledge to have fast failure.
5058 if (key->Hash() != String::cast(other)->Hash()) return false;
5059 return key->Equals(String::cast(other));
5060}
5061
5062
5063uint32_t StringDictionaryShape::Hash(String* key) {
5064 return key->Hash();
5065}
5066
5067
5068uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
5069 return String::cast(other)->Hash();
5070}
5071
5072
5073MaybeObject* StringDictionaryShape::AsObject(String* key) {
5074 return key;
5075}
5076
5077
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005078template <int entrysize>
5079bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
5080 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005081}
5082
5083
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005084template <int entrysize>
5085uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005086 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
5087 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005088}
5089
5090
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005091template <int entrysize>
5092uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
5093 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005094 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
5095 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005096}
5097
5098
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005099template <int entrysize>
5100MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005101 return key;
5102}
5103
5104
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005105void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005106 // No write barrier is needed since empty_fixed_array is not in new space.
5107 // Please note this function is used during marking:
5108 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00005109 // - IncrementalMarking::Step
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005110 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
5111 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005112}
5113
5114
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005115void JSArray::EnsureSize(int required_size) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005116 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005117 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005118 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
5119 if (elts->length() < required_size) {
5120 // Doubling in size would be overkill, but leave some slack to avoid
5121 // constantly growing.
5122 Expand(required_size + (required_size >> 3));
5123 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005124 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005125 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
5126 // Expand will allocate a new backing store in new space even if the size
5127 // we asked for isn't larger than what we had before.
5128 Expand(required_size);
5129 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005130}
5131
5132
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005133void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005134 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005135 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
5136}
5137
5138
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005139bool JSArray::AllowsSetElementsLength() {
5140 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
5141 ASSERT(result == !HasExternalArrayElements());
5142 return result;
5143}
5144
5145
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005146MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
5147 MaybeObject* maybe_result = EnsureCanContainElements(
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005148 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005149 if (maybe_result->IsFailure()) return maybe_result;
5150 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005151 IsFastDoubleElementsKind(GetElementsKind())) ||
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005152 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005153 (IsFastObjectElementsKind(GetElementsKind()) ||
5154 (IsFastSmiElementsKind(GetElementsKind()) &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005155 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00005156 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005157 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005158 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005159}
5160
5161
lrn@chromium.org303ada72010-10-27 09:33:13 +00005162MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005163 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005164 return GetHeap()->CopyFixedArray(this);
5165}
5166
5167
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005168MaybeObject* FixedDoubleArray::Copy() {
5169 if (length() == 0) return this;
5170 return GetHeap()->CopyFixedDoubleArray(this);
5171}
5172
5173
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005174void TypeFeedbackCells::SetAstId(int index, Smi* id) {
5175 set(1 + index * 2, id);
5176}
5177
5178
5179Smi* TypeFeedbackCells::AstId(int index) {
5180 return Smi::cast(get(1 + index * 2));
5181}
5182
5183
5184void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
5185 set(index * 2, cell);
5186}
5187
5188
5189JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
5190 return JSGlobalPropertyCell::cast(get(index * 2));
5191}
5192
5193
5194Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
5195 return isolate->factory()->the_hole_value();
5196}
5197
5198
5199Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
5200 return isolate->factory()->undefined_value();
5201}
5202
5203
5204Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
5205 return heap->raw_unchecked_the_hole_value();
5206}
5207
5208
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005209SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00005210SMI_ACCESSORS(TypeFeedbackInfo, ic_with_type_info_count,
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005211 kIcWithTypeinfoCountOffset)
5212ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
5213 kTypeFeedbackCellsOffset)
5214
5215
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00005216SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
5217
5218
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005219Relocatable::Relocatable(Isolate* isolate) {
5220 ASSERT(isolate == Isolate::Current());
5221 isolate_ = isolate;
5222 prev_ = isolate->relocatable_top();
5223 isolate->set_relocatable_top(this);
5224}
5225
5226
5227Relocatable::~Relocatable() {
5228 ASSERT(isolate_ == Isolate::Current());
5229 ASSERT_EQ(isolate_->relocatable_top(), this);
5230 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005231}
5232
5233
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005234int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
5235 return map->instance_size();
5236}
5237
5238
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005239void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005240 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005241 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005242}
5243
5244
5245template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005246void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005247 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005248 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005249}
5250
5251
5252void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
5253 typedef v8::String::ExternalAsciiStringResource Resource;
5254 v->VisitExternalAsciiString(
5255 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5256}
5257
5258
5259template<typename StaticVisitor>
5260void ExternalAsciiString::ExternalAsciiStringIterateBody() {
5261 typedef v8::String::ExternalAsciiStringResource Resource;
5262 StaticVisitor::VisitExternalAsciiString(
5263 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5264}
5265
5266
5267void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
5268 typedef v8::String::ExternalStringResource Resource;
5269 v->VisitExternalTwoByteString(
5270 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5271}
5272
5273
5274template<typename StaticVisitor>
5275void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
5276 typedef v8::String::ExternalStringResource Resource;
5277 StaticVisitor::VisitExternalTwoByteString(
5278 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5279}
5280
5281#define SLOT_ADDR(obj, offset) \
5282 reinterpret_cast<Object**>((obj)->address() + offset)
5283
5284template<int start_offset, int end_offset, int size>
5285void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
5286 HeapObject* obj,
5287 ObjectVisitor* v) {
5288 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
5289}
5290
5291
5292template<int start_offset>
5293void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
5294 int object_size,
5295 ObjectVisitor* v) {
5296 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
5297}
5298
5299#undef SLOT_ADDR
5300
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005301#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005302#undef CAST_ACCESSOR
5303#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005304#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005305#undef ACCESSORS_TO_SMI
5306#undef SMI_ACCESSORS
5307#undef BOOL_GETTER
5308#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005309#undef FIELD_ADDR
5310#undef READ_FIELD
5311#undef WRITE_FIELD
5312#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005313#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005314#undef READ_DOUBLE_FIELD
5315#undef WRITE_DOUBLE_FIELD
5316#undef READ_INT_FIELD
5317#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005318#undef READ_INTPTR_FIELD
5319#undef WRITE_INTPTR_FIELD
5320#undef READ_UINT32_FIELD
5321#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005322#undef READ_SHORT_FIELD
5323#undef WRITE_SHORT_FIELD
5324#undef READ_BYTE_FIELD
5325#undef WRITE_BYTE_FIELD
5326
5327
5328} } // namespace v8::internal
5329
5330#endif // V8_OBJECTS_INL_H_