blob: feca2719f3481c59feb9c8c712be07af03e67593 [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
verwaest@chromium.org753aee42012-07-17 16:15:42 +00003537MaybeObject* Map::AddTransition(String* key, Map* target) {
3538 if (HasTransitionArray()) return transitions()->CopyInsert(key, target);
3539 return TransitionArray::NewWith(key, target);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003540}
3541
verwaest@chromium.org753aee42012-07-17 16:15:42 +00003542
3543void Map::SetTransition(int transition_index, Map* target) {
3544 transitions()->SetTarget(transition_index, target);
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00003545}
3546
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003547
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003548// If the map is using the empty descriptor array, install a new empty
3549// descriptor array that will contain an elements transition.
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003550static MaybeObject* AllowTransitions(Map* map) {
3551 if (map->instance_descriptors()->MayContainTransitions()) return map;
3552 DescriptorArray* descriptors;
3553 MaybeObject* maybe_descriptors =
3554 DescriptorArray::Allocate(0, DescriptorArray::CANNOT_BE_SHARED);
3555 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
3556 map->set_instance_descriptors(descriptors);
3557 return descriptors;
3558}
3559
3560
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003561// If the descriptor is using the empty transition array, install a new empty
3562// transition array that will have place for an element transition.
3563static MaybeObject* EnsureHasTransitionArray(Map* map) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003564 if (map->HasTransitionArray()) return map;
3565
3566 AllowTransitions(map);
3567
3568 TransitionArray* transitions;
3569 MaybeObject* maybe_transitions = TransitionArray::Allocate(0);
3570 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
3571 MaybeObject* added_transitions = map->set_transitions(transitions);
3572 if (added_transitions->IsFailure()) return added_transitions;
3573 return transitions;
3574}
3575
3576
3577MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003578 MaybeObject* allow_elements = EnsureHasTransitionArray(this);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003579 if (allow_elements->IsFailure()) return allow_elements;
3580 transitions()->set_elements_transition(transitioned_map);
3581 return this;
3582}
3583
3584
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003585FixedArray* Map::GetPrototypeTransitions() {
3586 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
3587 if (!transitions()->HasPrototypeTransitions()) {
3588 return GetHeap()->empty_fixed_array();
3589 }
3590 return transitions()->GetPrototypeTransitions();
3591}
3592
3593
3594MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
3595 MaybeObject* allow_prototype = EnsureHasTransitionArray(this);
3596 if (allow_prototype->IsFailure()) return allow_prototype;
3597#ifdef DEBUG
3598 if (HasPrototypeTransitions()) {
3599 ASSERT(GetPrototypeTransitions() != proto_transitions);
3600 ZapPrototypeTransitions();
3601 }
3602#endif
3603 transitions()->SetPrototypeTransitions(proto_transitions);
3604 return this;
3605}
3606
3607
3608bool Map::HasPrototypeTransitions() {
3609 return HasTransitionArray() && transitions()->HasPrototypeTransitions();
3610}
3611
3612
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003613TransitionArray* Map::transitions() {
3614 return instance_descriptors()->transitions();
3615}
3616
3617
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003618void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003619#ifdef DEBUG
3620 ZapTransitions();
3621#endif
3622 DescriptorArray* descriptors = instance_descriptors();
3623 if (descriptors->number_of_descriptors() == 0) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003624 ClearDescriptorArray(heap, mode);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003625 } else {
3626 descriptors->ClearTransitions();
3627 }
3628}
3629
3630
3631MaybeObject* Map::set_transitions(TransitionArray* transitions_array) {
3632 MaybeObject* allow_transitions = AllowTransitions(this);
3633 if (allow_transitions->IsFailure()) return allow_transitions;
3634#ifdef DEBUG
3635 if (HasTransitionArray()) {
3636 ASSERT(transitions() != transitions_array);
3637 ZapTransitions();
3638 }
3639#endif
3640 instance_descriptors()->set_transitions(transitions_array);
3641 return this;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003642}
3643
3644
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003645void Map::init_back_pointer(Object* undefined) {
3646 ASSERT(undefined->IsUndefined());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003647 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, undefined);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003648}
3649
3650
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003651void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003652 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
3653 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
3654 (value->IsMap() && GetBackPointer()->IsUndefined()));
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003655 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset);
verwaest@chromium.org753aee42012-07-17 16:15:42 +00003656 if (object->IsDescriptorArray()) {
3657 DescriptorArray::cast(object)->set_back_pointer_storage(value);
3658 } else {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003659 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, value);
3660 CONDITIONAL_WRITE_BARRIER(
3661 GetHeap(), this, kInstanceDescriptorsOrBackPointerOffset, value, mode);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003662 }
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003663}
3664
3665
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003666// Can either be Smi (no transitions), normal transition array, or a transition
3667// array with the header overwritten as a Smi (thus iterating).
3668TransitionArray* Map::unchecked_transition_array() {
3669 ASSERT(HasTransitionArray());
3670 Object* object = *HeapObject::RawField(instance_descriptors(),
3671 DescriptorArray::kTransitionsOffset);
3672 ASSERT(!object->IsSmi());
3673 TransitionArray* transition_array = static_cast<TransitionArray*>(object);
3674 return transition_array;
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003675}
3676
3677
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003678HeapObject* Map::UncheckedPrototypeTransitions() {
3679 ASSERT(HasTransitionArray());
3680 ASSERT(unchecked_transition_array()->HasPrototypeTransitions());
3681 return unchecked_transition_array()->UncheckedPrototypeTransitions();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003682}
3683
3684
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003685ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003686ACCESSORS(Map, constructor, Object, kConstructorOffset)
3687
3688ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003689ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003690ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003691
3692ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3693ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003694ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003695
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003696ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003697
3698ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3699ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3700ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3701ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003702ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003703ACCESSORS(AccessorInfo, expected_receiver_type, Object,
3704 kExpectedReceiverTypeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003705
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003706ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3707ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3708
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003709ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3710ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3711ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3712
3713ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3714ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3715ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3716ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3717ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3718ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3719
3720ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3721ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3722
3723ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3724ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3725
3726ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3727ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003728ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3729 kPropertyAccessorsOffset)
3730ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3731 kPrototypeTemplateOffset)
3732ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3733ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3734 kNamedPropertyHandlerOffset)
3735ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3736 kIndexedPropertyHandlerOffset)
3737ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3738 kInstanceTemplateOffset)
3739ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3740ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003741ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3742 kInstanceCallHandlerOffset)
3743ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3744 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003745ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003746
3747ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003748ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3749 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003750
3751ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3752ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3753
3754ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3755
3756ACCESSORS(Script, source, Object, kSourceOffset)
3757ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003758ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003759ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
3760ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003761ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003762ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003763ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003764ACCESSORS_TO_SMI(Script, type, kTypeOffset)
3765ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
3766ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003767ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003768ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003769ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
3770 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003771
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003772#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003773ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3774ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3775ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3776ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3777
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003778ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
3779ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
3780ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003781ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003782#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003783
3784ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003785ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
3786 kOptimizedCodeMapOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003787ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3788ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003789ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3790 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003791ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003792ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3793ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003794ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003795ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3796 kThisPropertyAssignmentsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003797SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003798
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00003799
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003800BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3801 kHiddenPrototypeBit)
3802BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3803BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3804 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003805BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3806 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003807BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3808 kIsExpressionBit)
3809BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3810 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003811BOOL_GETTER(SharedFunctionInfo,
3812 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003813 has_only_simple_this_property_assignments,
3814 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003815BOOL_ACCESSORS(SharedFunctionInfo,
3816 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003817 allows_lazy_compilation,
3818 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003819BOOL_ACCESSORS(SharedFunctionInfo,
3820 compiler_hints,
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003821 allows_lazy_compilation_without_context,
3822 kAllowLazyCompilationWithoutContext)
3823BOOL_ACCESSORS(SharedFunctionInfo,
3824 compiler_hints,
whesse@chromium.org7b260152011-06-20 15:33:18 +00003825 uses_arguments,
3826 kUsesArguments)
3827BOOL_ACCESSORS(SharedFunctionInfo,
3828 compiler_hints,
3829 has_duplicate_parameters,
3830 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003831
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003832
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003833#if V8_HOST_ARCH_32_BIT
3834SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3835SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003836 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003837SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003838 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003839SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3840SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003841 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003842SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3843SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003844 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003845SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003846 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003847SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003848 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003849SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003850SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
3851SMI_ACCESSORS(SharedFunctionInfo,
3852 stress_deopt_counter,
3853 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003854#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003855
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003856#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003857 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003858 int holder::name() { \
3859 int value = READ_INT_FIELD(this, offset); \
3860 ASSERT(kHeapObjectTag == 1); \
3861 ASSERT((value & kHeapObjectTag) == 0); \
3862 return value >> 1; \
3863 } \
3864 void holder::set_##name(int value) { \
3865 ASSERT(kHeapObjectTag == 1); \
3866 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3867 (value & 0xC0000000) == 0x000000000); \
3868 WRITE_INT_FIELD(this, \
3869 offset, \
3870 (value << 1) & ~kHeapObjectTag); \
3871 }
3872
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003873#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3874 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003875 INT_ACCESSORS(holder, name, offset)
3876
3877
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003878PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003879PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3880 formal_parameter_count,
3881 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003882
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003883PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3884 expected_nof_properties,
3885 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003886PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3887
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003888PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3889PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3890 start_position_and_type,
3891 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003892
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003893PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3894 function_token_position,
3895 kFunctionTokenPositionOffset)
3896PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3897 compiler_hints,
3898 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003899
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003900PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3901 this_property_assignments_count,
3902 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003903PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003904
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003905PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, counters, kCountersOffset)
3906PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3907 stress_deopt_counter,
3908 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003909#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003910
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003911
3912int SharedFunctionInfo::construction_count() {
3913 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3914}
3915
3916
3917void SharedFunctionInfo::set_construction_count(int value) {
3918 ASSERT(0 <= value && value < 256);
3919 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3920}
3921
3922
whesse@chromium.org7b260152011-06-20 15:33:18 +00003923BOOL_ACCESSORS(SharedFunctionInfo,
3924 compiler_hints,
3925 live_objects_may_exist,
3926 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003927
3928
3929bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003930 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003931}
3932
3933
whesse@chromium.org7b260152011-06-20 15:33:18 +00003934BOOL_GETTER(SharedFunctionInfo,
3935 compiler_hints,
3936 optimization_disabled,
3937 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003938
3939
3940void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3941 set_compiler_hints(BooleanBit::set(compiler_hints(),
3942 kOptimizationDisabled,
3943 disable));
3944 // If disabling optimizations we reflect that in the code object so
3945 // it will not be counted as optimizable code.
3946 if ((code()->kind() == Code::FUNCTION) && disable) {
3947 code()->set_optimizable(false);
3948 }
3949}
3950
3951
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003952int SharedFunctionInfo::profiler_ticks() {
3953 if (code()->kind() != Code::FUNCTION) return 0;
3954 return code()->profiler_ticks();
3955}
3956
3957
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003958LanguageMode SharedFunctionInfo::language_mode() {
3959 int hints = compiler_hints();
3960 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3961 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3962 return EXTENDED_MODE;
3963 }
3964 return BooleanBit::get(hints, kStrictModeFunction)
3965 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003966}
3967
3968
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003969void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3970 // We only allow language mode transitions that go set the same language mode
3971 // again or go up in the chain:
3972 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3973 ASSERT(this->language_mode() == CLASSIC_MODE ||
3974 this->language_mode() == language_mode ||
3975 language_mode == EXTENDED_MODE);
3976 int hints = compiler_hints();
3977 hints = BooleanBit::set(
3978 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3979 hints = BooleanBit::set(
3980 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3981 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003982}
3983
3984
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003985bool SharedFunctionInfo::is_classic_mode() {
3986 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3987}
3988
3989BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3990 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003991BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3992BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3993 name_should_print_as_anonymous,
3994 kNameShouldPrintAsAnonymous)
3995BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3996BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00003997BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
3998BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
3999 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00004000BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004001BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_cache, kDontCache)
whesse@chromium.org7b260152011-06-20 15:33:18 +00004002
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004003void SharedFunctionInfo::BeforeVisitingPointers() {
4004 if (IsInobjectSlackTrackingInProgress()) DetachInitialMap();
4005
4006 // Flush optimized code map on major GC.
4007 // Note: we may experiment with rebuilding it or retaining entries
4008 // which should survive as we iterate through optimized functions
4009 // anyway.
4010 set_optimized_code_map(Smi::FromInt(0));
4011}
4012
4013
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004014ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
4015ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
4016
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00004017ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
4018
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00004019bool Script::HasValidSource() {
4020 Object* src = this->source();
4021 if (!src->IsString()) return true;
4022 String* src_str = String::cast(src);
4023 if (!StringShape(src_str).IsExternal()) return true;
4024 if (src_str->IsAsciiRepresentation()) {
4025 return ExternalAsciiString::cast(src)->resource() != NULL;
4026 } else if (src_str->IsTwoByteRepresentation()) {
4027 return ExternalTwoByteString::cast(src)->resource() != NULL;
4028 }
4029 return true;
4030}
4031
4032
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00004033void SharedFunctionInfo::DontAdaptArguments() {
4034 ASSERT(code()->kind() == Code::BUILTIN);
4035 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
4036}
4037
4038
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004039int SharedFunctionInfo::start_position() {
4040 return start_position_and_type() >> kStartPositionShift;
4041}
4042
4043
4044void SharedFunctionInfo::set_start_position(int start_position) {
4045 set_start_position_and_type((start_position << kStartPositionShift)
4046 | (start_position_and_type() & ~kStartPositionMask));
4047}
4048
4049
4050Code* SharedFunctionInfo::code() {
4051 return Code::cast(READ_FIELD(this, kCodeOffset));
4052}
4053
4054
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004055Code* SharedFunctionInfo::unchecked_code() {
4056 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
4057}
4058
4059
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004060void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004061 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004062 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004063}
4064
4065
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004066ScopeInfo* SharedFunctionInfo::scope_info() {
4067 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00004068}
4069
4070
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004071void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00004072 WriteBarrierMode mode) {
4073 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004074 CONDITIONAL_WRITE_BARRIER(GetHeap(),
4075 this,
4076 kScopeInfoOffset,
4077 reinterpret_cast<Object*>(value),
4078 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00004079}
4080
4081
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004082bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004083 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004084 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004085}
4086
4087
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004088bool SharedFunctionInfo::IsApiFunction() {
4089 return function_data()->IsFunctionTemplateInfo();
4090}
4091
4092
4093FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
4094 ASSERT(IsApiFunction());
4095 return FunctionTemplateInfo::cast(function_data());
4096}
4097
4098
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004099bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00004100 return function_data()->IsSmi();
4101}
4102
4103
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004104BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
4105 ASSERT(HasBuiltinFunctionId());
4106 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004107}
4108
4109
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004110int SharedFunctionInfo::code_age() {
4111 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
4112}
4113
4114
4115void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00004116 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
4117 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004118}
4119
4120
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004121int SharedFunctionInfo::ic_age() {
4122 return ICAgeBits::decode(counters());
4123}
4124
4125
4126void SharedFunctionInfo::set_ic_age(int ic_age) {
4127 set_counters(ICAgeBits::update(counters(), ic_age));
4128}
4129
4130
4131int SharedFunctionInfo::deopt_count() {
4132 return DeoptCountBits::decode(counters());
4133}
4134
4135
4136void SharedFunctionInfo::set_deopt_count(int deopt_count) {
4137 set_counters(DeoptCountBits::update(counters(), deopt_count));
4138}
4139
4140
4141void SharedFunctionInfo::increment_deopt_count() {
4142 int value = counters();
4143 int deopt_count = DeoptCountBits::decode(value);
4144 deopt_count = (deopt_count + 1) & DeoptCountBits::kMax;
4145 set_counters(DeoptCountBits::update(value, deopt_count));
4146}
4147
4148
4149int SharedFunctionInfo::opt_reenable_tries() {
4150 return OptReenableTriesBits::decode(counters());
4151}
4152
4153
4154void SharedFunctionInfo::set_opt_reenable_tries(int tries) {
4155 set_counters(OptReenableTriesBits::update(counters(), tries));
4156}
4157
4158
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004159bool SharedFunctionInfo::has_deoptimization_support() {
4160 Code* code = this->code();
4161 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
4162}
4163
4164
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004165void SharedFunctionInfo::TryReenableOptimization() {
4166 int tries = opt_reenable_tries();
4167 set_opt_reenable_tries((tries + 1) & OptReenableTriesBits::kMax);
4168 // We reenable optimization whenever the number of tries is a large
4169 // enough power of 2.
4170 if (tries >= 16 && (((tries - 1) & tries) == 0)) {
4171 set_optimization_disabled(false);
4172 set_opt_count(0);
4173 set_deopt_count(0);
4174 code()->set_optimizable(true);
4175 }
4176}
4177
4178
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004179bool JSFunction::IsBuiltin() {
4180 return context()->global()->IsJSBuiltinsObject();
4181}
4182
4183
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004184bool JSFunction::NeedsArgumentsAdaption() {
4185 return shared()->formal_parameter_count() !=
4186 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
4187}
4188
4189
4190bool JSFunction::IsOptimized() {
4191 return code()->kind() == Code::OPTIMIZED_FUNCTION;
4192}
4193
4194
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00004195bool JSFunction::IsOptimizable() {
4196 return code()->kind() == Code::FUNCTION && code()->optimizable();
4197}
4198
4199
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004200bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004201 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004202}
4203
4204
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004205Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004206 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004207}
4208
4209
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004210Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004211 return reinterpret_cast<Code*>(
4212 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004213}
4214
4215
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004216void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004217 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004218 Address entry = value->entry();
4219 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004220 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
4221 this,
4222 HeapObject::RawField(this, kCodeEntryOffset),
4223 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004224}
4225
4226
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004227void JSFunction::ReplaceCode(Code* code) {
4228 bool was_optimized = IsOptimized();
4229 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
4230
4231 set_code(code);
4232
4233 // Add/remove the function from the list of optimized functions for this
4234 // context based on the state change.
4235 if (!was_optimized && is_optimized) {
4236 context()->global_context()->AddOptimizedFunction(this);
4237 }
4238 if (was_optimized && !is_optimized) {
4239 context()->global_context()->RemoveOptimizedFunction(this);
4240 }
4241}
4242
4243
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004244Context* JSFunction::context() {
4245 return Context::cast(READ_FIELD(this, kContextOffset));
4246}
4247
4248
4249Object* JSFunction::unchecked_context() {
4250 return READ_FIELD(this, kContextOffset);
4251}
4252
4253
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004254SharedFunctionInfo* JSFunction::unchecked_shared() {
4255 return reinterpret_cast<SharedFunctionInfo*>(
4256 READ_FIELD(this, kSharedFunctionInfoOffset));
4257}
4258
4259
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004260void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004261 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004262 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004263 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004264}
4265
4266ACCESSORS(JSFunction, prototype_or_initial_map, Object,
4267 kPrototypeOrInitialMapOffset)
4268
4269
4270Map* JSFunction::initial_map() {
4271 return Map::cast(prototype_or_initial_map());
4272}
4273
4274
4275void JSFunction::set_initial_map(Map* value) {
4276 set_prototype_or_initial_map(value);
4277}
4278
4279
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004280MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
4281 Map* initial_map) {
4282 Context* global_context = context()->global_context();
4283 Object* array_function =
4284 global_context->get(Context::ARRAY_FUNCTION_INDEX);
4285 if (array_function->IsJSFunction() &&
4286 this == JSFunction::cast(array_function)) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004287 // Replace all of the cached initial array maps in the global context with
4288 // the appropriate transitioned elements kind maps.
4289 Heap* heap = GetHeap();
4290 MaybeObject* maybe_maps =
4291 heap->AllocateFixedArrayWithHoles(kElementsKindCount);
4292 FixedArray* maps;
4293 if (!maybe_maps->To(&maps)) return maybe_maps;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004294
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004295 Map* current_map = initial_map;
4296 ElementsKind kind = current_map->elements_kind();
4297 ASSERT(kind == GetInitialFastElementsKind());
4298 maps->set(kind, current_map);
4299 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
4300 i < kFastElementsKindCount; ++i) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004301 Map* new_map;
4302 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
4303 MaybeObject* maybe_new_map =
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004304 current_map->CopyAsElementsKind(next_kind, INSERT_TRANSITION);
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004305 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
4306 maps->set(next_kind, new_map);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004307 current_map = new_map;
4308 }
4309 global_context->set_js_array_maps(maps);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004310 }
4311 set_initial_map(initial_map);
4312 return this;
4313}
4314
4315
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004316bool JSFunction::has_initial_map() {
4317 return prototype_or_initial_map()->IsMap();
4318}
4319
4320
4321bool JSFunction::has_instance_prototype() {
4322 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4323}
4324
4325
4326bool JSFunction::has_prototype() {
4327 return map()->has_non_instance_prototype() || has_instance_prototype();
4328}
4329
4330
4331Object* JSFunction::instance_prototype() {
4332 ASSERT(has_instance_prototype());
4333 if (has_initial_map()) return initial_map()->prototype();
4334 // When there is no initial map and the prototype is a JSObject, the
4335 // initial map field is used for the prototype field.
4336 return prototype_or_initial_map();
4337}
4338
4339
4340Object* JSFunction::prototype() {
4341 ASSERT(has_prototype());
4342 // If the function's prototype property has been set to a non-JSObject
4343 // value, that value is stored in the constructor field of the map.
4344 if (map()->has_non_instance_prototype()) return map()->constructor();
4345 return instance_prototype();
4346}
4347
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004348
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00004349bool JSFunction::should_have_prototype() {
4350 return map()->function_with_prototype();
4351}
4352
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004353
4354bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004355 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004356}
4357
4358
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004359FixedArray* JSFunction::literals() {
4360 ASSERT(!shared()->bound());
4361 return literals_or_bindings();
4362}
4363
4364
4365void JSFunction::set_literals(FixedArray* literals) {
4366 ASSERT(!shared()->bound());
4367 set_literals_or_bindings(literals);
4368}
4369
4370
4371FixedArray* JSFunction::function_bindings() {
4372 ASSERT(shared()->bound());
4373 return literals_or_bindings();
4374}
4375
4376
4377void JSFunction::set_function_bindings(FixedArray* bindings) {
4378 ASSERT(shared()->bound());
4379 // Bound function literal may be initialized to the empty fixed array
4380 // before the bindings are set.
4381 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4382 bindings->map() == GetHeap()->fixed_cow_array_map());
4383 set_literals_or_bindings(bindings);
4384}
4385
4386
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004387int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004388 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004389 return literals()->length();
4390}
4391
4392
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004393Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004394 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004395 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004396}
4397
4398
4399void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4400 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004401 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004402 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004403 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004404}
4405
4406
4407Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004408 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004409 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4410}
4411
4412
4413void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4414 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004415 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004416 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004417 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004418}
4419
4420
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004421ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004422ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004423ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4424ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4425
4426
4427void JSProxy::InitializeBody(int object_size, Object* value) {
4428 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4429 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4430 WRITE_FIELD(this, offset, value);
4431 }
4432}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004433
4434
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004435ACCESSORS(JSSet, table, Object, kTableOffset)
4436ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004437ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4438ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004439
4440
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004441Address Foreign::foreign_address() {
4442 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004443}
4444
4445
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004446void Foreign::set_foreign_address(Address value) {
4447 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004448}
4449
4450
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004451ACCESSORS(JSModule, context, Object, kContextOffset)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004452ACCESSORS(JSModule, scope_info, ScopeInfo, kScopeInfoOffset)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004453
4454
4455JSModule* JSModule::cast(Object* obj) {
4456 ASSERT(obj->IsJSModule());
4457 ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
4458 return reinterpret_cast<JSModule*>(obj);
4459}
4460
4461
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004462ACCESSORS(JSValue, value, Object, kValueOffset)
4463
4464
4465JSValue* JSValue::cast(Object* obj) {
4466 ASSERT(obj->IsJSValue());
4467 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4468 return reinterpret_cast<JSValue*>(obj);
4469}
4470
4471
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004472ACCESSORS(JSDate, value, Object, kValueOffset)
4473ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4474ACCESSORS(JSDate, year, Object, kYearOffset)
4475ACCESSORS(JSDate, month, Object, kMonthOffset)
4476ACCESSORS(JSDate, day, Object, kDayOffset)
4477ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4478ACCESSORS(JSDate, hour, Object, kHourOffset)
4479ACCESSORS(JSDate, min, Object, kMinOffset)
4480ACCESSORS(JSDate, sec, Object, kSecOffset)
4481
4482
4483JSDate* JSDate::cast(Object* obj) {
4484 ASSERT(obj->IsJSDate());
4485 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4486 return reinterpret_cast<JSDate*>(obj);
4487}
4488
4489
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004490ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4491ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4492ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4493ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4494ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4495SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4496SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4497
4498
4499JSMessageObject* JSMessageObject::cast(Object* obj) {
4500 ASSERT(obj->IsJSMessageObject());
4501 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4502 return reinterpret_cast<JSMessageObject*>(obj);
4503}
4504
4505
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004506INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004507ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004508ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004509ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004510ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004511ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00004512INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004513
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004514byte* Code::instruction_start() {
4515 return FIELD_ADDR(this, kHeaderSize);
4516}
4517
4518
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004519byte* Code::instruction_end() {
4520 return instruction_start() + instruction_size();
4521}
4522
4523
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004524int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004525 return RoundUp(instruction_size(), kObjectAlignment);
4526}
4527
4528
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004529FixedArray* Code::unchecked_deoptimization_data() {
4530 return reinterpret_cast<FixedArray*>(
4531 READ_FIELD(this, kDeoptimizationDataOffset));
4532}
4533
4534
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004535ByteArray* Code::unchecked_relocation_info() {
4536 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004537}
4538
4539
4540byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004541 return unchecked_relocation_info()->GetDataStartAddress();
4542}
4543
4544
4545int Code::relocation_size() {
4546 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004547}
4548
4549
4550byte* Code::entry() {
4551 return instruction_start();
4552}
4553
4554
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004555bool Code::contains(byte* inner_pointer) {
4556 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004557}
4558
4559
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004560ACCESSORS(JSArray, length, Object, kLengthOffset)
4561
4562
ager@chromium.org236ad962008-09-25 09:45:57 +00004563ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004564
4565
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004566JSRegExp::Type JSRegExp::TypeTag() {
4567 Object* data = this->data();
4568 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4569 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4570 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004571}
4572
4573
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004574JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4575 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4576 return static_cast<JSRegExp::Type>(smi->value());
4577}
4578
4579
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004580int JSRegExp::CaptureCount() {
4581 switch (TypeTag()) {
4582 case ATOM:
4583 return 0;
4584 case IRREGEXP:
4585 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4586 default:
4587 UNREACHABLE();
4588 return -1;
4589 }
4590}
4591
4592
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004593JSRegExp::Flags JSRegExp::GetFlags() {
4594 ASSERT(this->data()->IsFixedArray());
4595 Object* data = this->data();
4596 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4597 return Flags(smi->value());
4598}
4599
4600
4601String* JSRegExp::Pattern() {
4602 ASSERT(this->data()->IsFixedArray());
4603 Object* data = this->data();
4604 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4605 return pattern;
4606}
4607
4608
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004609Object* JSRegExp::DataAt(int index) {
4610 ASSERT(TypeTag() != NOT_COMPILED);
4611 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004612}
4613
4614
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004615Object* JSRegExp::DataAtUnchecked(int index) {
4616 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4617 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4618 return READ_FIELD(fa, offset);
4619}
4620
4621
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004622void JSRegExp::SetDataAt(int index, Object* value) {
4623 ASSERT(TypeTag() != NOT_COMPILED);
4624 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4625 FixedArray::cast(data())->set(index, value);
4626}
4627
4628
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004629void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4630 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4631 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4632 if (value->IsSmi()) {
4633 fa->set_unchecked(index, Smi::cast(value));
4634 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004635 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004636 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4637 }
4638}
4639
4640
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004641ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004642 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004643#if DEBUG
4644 FixedArrayBase* fixed_array =
4645 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4646 Map* map = fixed_array->map();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004647 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
4648 (map == GetHeap()->fixed_array_map() ||
4649 map == GetHeap()->fixed_cow_array_map())) ||
4650 (IsFastDoubleElementsKind(kind) &&
4651 (fixed_array->IsFixedDoubleArray() ||
4652 fixed_array == GetHeap()->empty_fixed_array())) ||
4653 (kind == DICTIONARY_ELEMENTS &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004654 fixed_array->IsFixedArray() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004655 fixed_array->IsDictionary()) ||
4656 (kind > DICTIONARY_ELEMENTS));
4657 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4658 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004659#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004660 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004661}
4662
4663
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004664ElementsAccessor* JSObject::GetElementsAccessor() {
4665 return ElementsAccessor::ForKind(GetElementsKind());
4666}
4667
4668
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004669bool JSObject::HasFastObjectElements() {
4670 return IsFastObjectElementsKind(GetElementsKind());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004671}
4672
4673
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004674bool JSObject::HasFastSmiElements() {
4675 return IsFastSmiElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004676}
4677
4678
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004679bool JSObject::HasFastSmiOrObjectElements() {
4680 return IsFastSmiOrObjectElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004681}
4682
4683
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004684bool JSObject::HasFastDoubleElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004685 return IsFastDoubleElementsKind(GetElementsKind());
4686}
4687
4688
4689bool JSObject::HasFastHoleyElements() {
4690 return IsFastHoleyElementsKind(GetElementsKind());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004691}
4692
4693
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004694bool JSObject::HasDictionaryElements() {
4695 return GetElementsKind() == DICTIONARY_ELEMENTS;
4696}
4697
4698
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004699bool JSObject::HasNonStrictArgumentsElements() {
4700 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4701}
4702
4703
ager@chromium.org3811b432009-10-28 14:53:37 +00004704bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004705 HeapObject* array = elements();
4706 ASSERT(array != NULL);
4707 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004708}
4709
4710
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004711#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4712bool JSObject::HasExternal##name##Elements() { \
4713 HeapObject* array = elements(); \
4714 ASSERT(array != NULL); \
4715 if (!array->IsHeapObject()) \
4716 return false; \
4717 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004718}
4719
4720
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004721EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4722EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4723EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4724EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4725 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4726EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4727EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4728 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4729EXTERNAL_ELEMENTS_CHECK(Float,
4730 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004731EXTERNAL_ELEMENTS_CHECK(Double,
4732 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004733EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004734
4735
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004736bool JSObject::HasNamedInterceptor() {
4737 return map()->has_named_interceptor();
4738}
4739
4740
4741bool JSObject::HasIndexedInterceptor() {
4742 return map()->has_indexed_interceptor();
4743}
4744
4745
lrn@chromium.org303ada72010-10-27 09:33:13 +00004746MaybeObject* JSObject::EnsureWritableFastElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004747 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004748 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004749 Isolate* isolate = GetIsolate();
4750 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004751 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004752 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4753 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004754 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4755 return maybe_writable_elems;
4756 }
4757 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004758 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004759 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004760 return writable_elems;
4761}
4762
4763
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004764StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004765 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004766 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004767}
4768
4769
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004770SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004771 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004772 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004773}
4774
4775
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004776bool String::IsHashFieldComputed(uint32_t field) {
4777 return (field & kHashNotComputedMask) == 0;
4778}
4779
4780
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004781bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004782 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004783}
4784
4785
4786uint32_t String::Hash() {
4787 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004788 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004789 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004790 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004791 return ComputeAndSetHash();
4792}
4793
4794
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004795StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004796 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004797 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004798 array_index_(0),
4799 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4800 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004801 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004802 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004803}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004804
4805
4806bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004807 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004808}
4809
4810
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004811void StringHasher::AddCharacter(uint32_t c) {
4812 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4813 AddSurrogatePair(c); // Not inlined.
4814 return;
4815 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004816 // Use the Jenkins one-at-a-time hash function to update the hash
4817 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004818 raw_running_hash_ += c;
4819 raw_running_hash_ += (raw_running_hash_ << 10);
4820 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004821 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004822 if (is_array_index_) {
4823 if (c < '0' || c > '9') {
4824 is_array_index_ = false;
4825 } else {
4826 int d = c - '0';
4827 if (is_first_char_) {
4828 is_first_char_ = false;
4829 if (c == '0' && length_ > 1) {
4830 is_array_index_ = false;
4831 return;
4832 }
4833 }
4834 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4835 is_array_index_ = false;
4836 } else {
4837 array_index_ = array_index_ * 10 + d;
4838 }
4839 }
4840 }
4841}
4842
4843
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004844void StringHasher::AddCharacterNoIndex(uint32_t c) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00004845 ASSERT(!is_array_index());
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004846 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4847 AddSurrogatePairNoIndex(c); // Not inlined.
4848 return;
4849 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004850 raw_running_hash_ += c;
4851 raw_running_hash_ += (raw_running_hash_ << 10);
4852 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4853}
4854
4855
4856uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004857 // Get the calculated raw hash value and do some more bit ops to distribute
4858 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004859 uint32_t result = raw_running_hash_;
4860 result += (result << 3);
4861 result ^= (result >> 11);
4862 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004863 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004864 result = 27;
4865 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004866 return result;
4867}
4868
4869
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004870template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004871uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4872 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004873 if (!hasher.has_trivial_hash()) {
4874 int i;
4875 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4876 hasher.AddCharacter(chars[i]);
4877 }
4878 for (; i < length; i++) {
4879 hasher.AddCharacterNoIndex(chars[i]);
4880 }
4881 }
4882 return hasher.GetHashField();
4883}
4884
4885
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004886bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004887 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004888 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4889 return false;
4890 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004891 return SlowAsArrayIndex(index);
4892}
4893
4894
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004895Object* JSReceiver::GetPrototype() {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004896 return map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004897}
4898
4899
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00004900Object* JSReceiver::GetConstructor() {
4901 return map()->constructor();
4902}
4903
4904
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004905bool JSReceiver::HasProperty(String* name) {
4906 if (IsJSProxy()) {
4907 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4908 }
4909 return GetPropertyAttribute(name) != ABSENT;
4910}
4911
4912
4913bool JSReceiver::HasLocalProperty(String* name) {
4914 if (IsJSProxy()) {
4915 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4916 }
4917 return GetLocalPropertyAttribute(name) != ABSENT;
4918}
4919
4920
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004921PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004922 return GetPropertyAttributeWithReceiver(this, key);
4923}
4924
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004925// TODO(504): this may be useful in other places too where JSGlobalProxy
4926// is used.
4927Object* JSObject::BypassGlobalProxy() {
4928 if (IsJSGlobalProxy()) {
4929 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004930 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004931 ASSERT(proto->IsJSGlobalObject());
4932 return proto;
4933 }
4934 return this;
4935}
4936
4937
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004938MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4939 return IsJSProxy()
4940 ? JSProxy::cast(this)->GetIdentityHash(flag)
4941 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004942}
4943
4944
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004945bool JSReceiver::HasElement(uint32_t index) {
4946 if (IsJSProxy()) {
4947 return JSProxy::cast(this)->HasElementWithHandler(index);
4948 }
4949 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004950}
4951
4952
4953bool AccessorInfo::all_can_read() {
4954 return BooleanBit::get(flag(), kAllCanReadBit);
4955}
4956
4957
4958void AccessorInfo::set_all_can_read(bool value) {
4959 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4960}
4961
4962
4963bool AccessorInfo::all_can_write() {
4964 return BooleanBit::get(flag(), kAllCanWriteBit);
4965}
4966
4967
4968void AccessorInfo::set_all_can_write(bool value) {
4969 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4970}
4971
4972
ager@chromium.org870a0b62008-11-04 11:43:05 +00004973bool AccessorInfo::prohibits_overwriting() {
4974 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4975}
4976
4977
4978void AccessorInfo::set_prohibits_overwriting(bool value) {
4979 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4980}
4981
4982
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004983PropertyAttributes AccessorInfo::property_attributes() {
4984 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4985}
4986
4987
4988void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004989 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004990}
4991
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004992
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004993bool AccessorInfo::IsCompatibleReceiver(Object* receiver) {
4994 Object* function_template = expected_receiver_type();
4995 if (!function_template->IsFunctionTemplateInfo()) return true;
4996 return receiver->IsInstanceOf(FunctionTemplateInfo::cast(function_template));
4997}
4998
4999
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005000template<typename Shape, typename Key>
5001void Dictionary<Shape, Key>::SetEntry(int entry,
5002 Object* key,
5003 Object* value) {
5004 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
5005}
5006
5007
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005008template<typename Shape, typename Key>
5009void Dictionary<Shape, Key>::SetEntry(int entry,
5010 Object* key,
5011 Object* value,
5012 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00005013 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005014 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005015 AssertNoAllocation no_gc;
5016 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005017 FixedArray::set(index, key, mode);
5018 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005019 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005020}
5021
5022
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005023bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
5024 ASSERT(other->IsNumber());
5025 return key == static_cast<uint32_t>(other->Number());
5026}
5027
5028
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005029uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
5030 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005031}
5032
5033
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005034uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
5035 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005036 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005037 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005038}
5039
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005040uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
5041 return ComputeIntegerHash(key, seed);
5042}
5043
5044uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
5045 uint32_t seed,
5046 Object* other) {
5047 ASSERT(other->IsNumber());
5048 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
5049}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005050
5051MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
5052 return Isolate::Current()->heap()->NumberFromUint32(key);
5053}
5054
5055
5056bool StringDictionaryShape::IsMatch(String* key, Object* other) {
5057 // We know that all entries in a hash table had their hash keys created.
5058 // Use that knowledge to have fast failure.
5059 if (key->Hash() != String::cast(other)->Hash()) return false;
5060 return key->Equals(String::cast(other));
5061}
5062
5063
5064uint32_t StringDictionaryShape::Hash(String* key) {
5065 return key->Hash();
5066}
5067
5068
5069uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
5070 return String::cast(other)->Hash();
5071}
5072
5073
5074MaybeObject* StringDictionaryShape::AsObject(String* key) {
5075 return key;
5076}
5077
5078
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005079template <int entrysize>
5080bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
5081 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005082}
5083
5084
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005085template <int entrysize>
5086uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005087 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
5088 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005089}
5090
5091
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005092template <int entrysize>
5093uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
5094 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005095 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
5096 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005097}
5098
5099
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005100template <int entrysize>
5101MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005102 return key;
5103}
5104
5105
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005106void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005107 // No write barrier is needed since empty_fixed_array is not in new space.
5108 // Please note this function is used during marking:
5109 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00005110 // - IncrementalMarking::Step
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005111 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
5112 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005113}
5114
5115
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005116void JSArray::EnsureSize(int required_size) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005117 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005118 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005119 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
5120 if (elts->length() < required_size) {
5121 // Doubling in size would be overkill, but leave some slack to avoid
5122 // constantly growing.
5123 Expand(required_size + (required_size >> 3));
5124 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005125 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005126 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
5127 // Expand will allocate a new backing store in new space even if the size
5128 // we asked for isn't larger than what we had before.
5129 Expand(required_size);
5130 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005131}
5132
5133
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005134void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005135 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005136 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
5137}
5138
5139
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005140bool JSArray::AllowsSetElementsLength() {
5141 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
5142 ASSERT(result == !HasExternalArrayElements());
5143 return result;
5144}
5145
5146
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005147MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
5148 MaybeObject* maybe_result = EnsureCanContainElements(
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005149 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005150 if (maybe_result->IsFailure()) return maybe_result;
5151 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005152 IsFastDoubleElementsKind(GetElementsKind())) ||
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005153 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005154 (IsFastObjectElementsKind(GetElementsKind()) ||
5155 (IsFastSmiElementsKind(GetElementsKind()) &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005156 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00005157 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005158 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005159 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005160}
5161
5162
lrn@chromium.org303ada72010-10-27 09:33:13 +00005163MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005164 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005165 return GetHeap()->CopyFixedArray(this);
5166}
5167
5168
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005169MaybeObject* FixedDoubleArray::Copy() {
5170 if (length() == 0) return this;
5171 return GetHeap()->CopyFixedDoubleArray(this);
5172}
5173
5174
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005175void TypeFeedbackCells::SetAstId(int index, Smi* id) {
5176 set(1 + index * 2, id);
5177}
5178
5179
5180Smi* TypeFeedbackCells::AstId(int index) {
5181 return Smi::cast(get(1 + index * 2));
5182}
5183
5184
5185void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
5186 set(index * 2, cell);
5187}
5188
5189
5190JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
5191 return JSGlobalPropertyCell::cast(get(index * 2));
5192}
5193
5194
5195Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
5196 return isolate->factory()->the_hole_value();
5197}
5198
5199
5200Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
5201 return isolate->factory()->undefined_value();
5202}
5203
5204
5205Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
5206 return heap->raw_unchecked_the_hole_value();
5207}
5208
5209
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005210SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00005211SMI_ACCESSORS(TypeFeedbackInfo, ic_with_type_info_count,
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005212 kIcWithTypeinfoCountOffset)
5213ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
5214 kTypeFeedbackCellsOffset)
5215
5216
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00005217SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
5218
5219
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005220Relocatable::Relocatable(Isolate* isolate) {
5221 ASSERT(isolate == Isolate::Current());
5222 isolate_ = isolate;
5223 prev_ = isolate->relocatable_top();
5224 isolate->set_relocatable_top(this);
5225}
5226
5227
5228Relocatable::~Relocatable() {
5229 ASSERT(isolate_ == Isolate::Current());
5230 ASSERT_EQ(isolate_->relocatable_top(), this);
5231 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005232}
5233
5234
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005235int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
5236 return map->instance_size();
5237}
5238
5239
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005240void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005241 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005242 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005243}
5244
5245
5246template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005247void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005248 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005249 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005250}
5251
5252
5253void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
5254 typedef v8::String::ExternalAsciiStringResource Resource;
5255 v->VisitExternalAsciiString(
5256 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5257}
5258
5259
5260template<typename StaticVisitor>
5261void ExternalAsciiString::ExternalAsciiStringIterateBody() {
5262 typedef v8::String::ExternalAsciiStringResource Resource;
5263 StaticVisitor::VisitExternalAsciiString(
5264 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5265}
5266
5267
5268void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
5269 typedef v8::String::ExternalStringResource Resource;
5270 v->VisitExternalTwoByteString(
5271 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5272}
5273
5274
5275template<typename StaticVisitor>
5276void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
5277 typedef v8::String::ExternalStringResource Resource;
5278 StaticVisitor::VisitExternalTwoByteString(
5279 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5280}
5281
5282#define SLOT_ADDR(obj, offset) \
5283 reinterpret_cast<Object**>((obj)->address() + offset)
5284
5285template<int start_offset, int end_offset, int size>
5286void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
5287 HeapObject* obj,
5288 ObjectVisitor* v) {
5289 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
5290}
5291
5292
5293template<int start_offset>
5294void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
5295 int object_size,
5296 ObjectVisitor* v) {
5297 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
5298}
5299
5300#undef SLOT_ADDR
5301
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005302#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005303#undef CAST_ACCESSOR
5304#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005305#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005306#undef ACCESSORS_TO_SMI
5307#undef SMI_ACCESSORS
5308#undef BOOL_GETTER
5309#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005310#undef FIELD_ADDR
5311#undef READ_FIELD
5312#undef WRITE_FIELD
5313#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005314#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005315#undef READ_DOUBLE_FIELD
5316#undef WRITE_DOUBLE_FIELD
5317#undef READ_INT_FIELD
5318#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005319#undef READ_INTPTR_FIELD
5320#undef WRITE_INTPTR_FIELD
5321#undef READ_UINT32_FIELD
5322#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005323#undef READ_SHORT_FIELD
5324#undef WRITE_SHORT_FIELD
5325#undef READ_BYTE_FIELD
5326#undef WRITE_BYTE_FIELD
5327
5328
5329} } // namespace v8::internal
5330
5331#endif // V8_OBJECTS_INL_H_