blob: e47b44b3833aa88859c26aa5ed0afaa0e172f8f8 [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>
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001955int LinearSearch(T* array, String* name, int len) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001956 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();
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001960 if (current_hash > hash) break;
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001961 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.org304cc332012-07-24 07:59:48 +00001978 return LinearSearch(array, 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
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002113int DescriptorArray::Append(Descriptor* desc,
2114 const WhitenessWitness& witness,
2115 int number_of_set_descriptors) {
2116 int descriptor_number = number_of_set_descriptors;
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00002117 int enumeration_index = descriptor_number + 1;
2118 desc->SetEnumerationIndex(enumeration_index);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002119
2120 uint32_t hash = desc->GetKey()->Hash();
2121
2122 for (; descriptor_number > 0; --descriptor_number) {
2123 String* key = GetKey(descriptor_number - 1);
2124 if (key->Hash() <= hash) break;
2125 Object* value = GetValue(descriptor_number - 1);
2126 PropertyDetails details = GetDetails(descriptor_number - 1);
2127 Descriptor moved_descriptor(key, value, details);
2128 Set(descriptor_number, &moved_descriptor, witness);
2129 }
2130
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00002131 Set(descriptor_number, desc, witness);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002132 return descriptor_number;
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00002133}
2134
2135
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002136void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2137 int first, int second) {
2138 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002139 NoIncrementalWriteBarrierSwap(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002140 ToValueIndex(first),
2141 ToValueIndex(second));
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002142 NoIncrementalWriteBarrierSwap(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002143 ToDetailsIndex(first),
2144 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002145}
2146
2147
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002148FixedArray::WhitenessWitness::WhitenessWitness(FixedArray* array)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002149 : marking_(array->GetHeap()->incremental_marking()) {
2150 marking_->EnterNoMarkingScope();
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002151 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002152}
2153
2154
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002155FixedArray::WhitenessWitness::~WhitenessWitness() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002156 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002157}
2158
2159
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002160template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002161int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2162 const int kMinCapacity = 32;
2163 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2164 if (capacity < kMinCapacity) {
2165 capacity = kMinCapacity; // Guarantee min capacity.
2166 }
2167 return capacity;
2168}
2169
2170
2171template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002172int HashTable<Shape, Key>::FindEntry(Key key) {
2173 return FindEntry(GetIsolate(), key);
2174}
2175
2176
2177// Find entry for key otherwise return kNotFound.
2178template<typename Shape, typename Key>
2179int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2180 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002181 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002182 uint32_t count = 1;
2183 // EnsureCapacity will guarantee the hash table is never full.
2184 while (true) {
2185 Object* element = KeyAt(entry);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002186 // Empty entry.
2187 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2188 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002189 Shape::IsMatch(key, element)) return entry;
2190 entry = NextProbe(entry, count++, capacity);
2191 }
2192 return kNotFound;
2193}
2194
2195
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002196bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002197 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002198 if (!max_index_object->IsSmi()) return false;
2199 return 0 !=
2200 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2201}
2202
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002203uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002204 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002205 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002206 if (!max_index_object->IsSmi()) return 0;
2207 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2208 return value >> kRequiresSlowElementsTagSize;
2209}
2210
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002211void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002212 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002213}
2214
2215
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002216// ------------------------------------
2217// Cast operations
2218
2219
2220CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002221CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002222CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002223CAST_ACCESSOR(DeoptimizationInputData)
2224CAST_ACCESSOR(DeoptimizationOutputData)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002225CAST_ACCESSOR(TypeFeedbackCells)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002226CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002227CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002228CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002229CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002230CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002231CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002232CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002233CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002234CAST_ACCESSOR(String)
2235CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002236CAST_ACCESSOR(SeqAsciiString)
2237CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002238CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002239CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002240CAST_ACCESSOR(ExternalString)
2241CAST_ACCESSOR(ExternalAsciiString)
2242CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002243CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002244CAST_ACCESSOR(JSObject)
2245CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002246CAST_ACCESSOR(HeapObject)
2247CAST_ACCESSOR(HeapNumber)
2248CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002249CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002250CAST_ACCESSOR(SharedFunctionInfo)
2251CAST_ACCESSOR(Map)
2252CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002253CAST_ACCESSOR(GlobalObject)
2254CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002255CAST_ACCESSOR(JSGlobalObject)
2256CAST_ACCESSOR(JSBuiltinsObject)
2257CAST_ACCESSOR(Code)
2258CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002259CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002260CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002261CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002262CAST_ACCESSOR(JSSet)
2263CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002264CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002265CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002266CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002267CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002268CAST_ACCESSOR(ExternalArray)
2269CAST_ACCESSOR(ExternalByteArray)
2270CAST_ACCESSOR(ExternalUnsignedByteArray)
2271CAST_ACCESSOR(ExternalShortArray)
2272CAST_ACCESSOR(ExternalUnsignedShortArray)
2273CAST_ACCESSOR(ExternalIntArray)
2274CAST_ACCESSOR(ExternalUnsignedIntArray)
2275CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002276CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002277CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002278CAST_ACCESSOR(Struct)
2279
2280
2281#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2282 STRUCT_LIST(MAKE_STRUCT_CAST)
2283#undef MAKE_STRUCT_CAST
2284
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002285
2286template <typename Shape, typename Key>
2287HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002288 ASSERT(obj->IsHashTable());
2289 return reinterpret_cast<HashTable*>(obj);
2290}
2291
2292
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002293SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002294SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002295
ager@chromium.orgac091b72010-05-05 07:34:42 +00002296SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002297
2298
2299uint32_t String::hash_field() {
2300 return READ_UINT32_FIELD(this, kHashFieldOffset);
2301}
2302
2303
2304void String::set_hash_field(uint32_t value) {
2305 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002306#if V8_HOST_ARCH_64_BIT
2307 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2308#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002309}
2310
2311
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002312bool String::Equals(String* other) {
2313 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002314 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2315 return false;
2316 }
2317 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002318}
2319
2320
lrn@chromium.org303ada72010-10-27 09:33:13 +00002321MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002322 if (!StringShape(this).IsCons()) return this;
2323 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002324 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002325 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002326}
2327
2328
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002329String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002330 MaybeObject* flat = TryFlatten(pretenure);
2331 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002332 if (!flat->ToObject(&successfully_flattened)) return this;
2333 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002334}
2335
2336
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002337uint16_t String::Get(int index) {
2338 ASSERT(index >= 0 && index < length());
2339 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002340 case kSeqStringTag | kAsciiStringTag:
2341 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2342 case kSeqStringTag | kTwoByteStringTag:
2343 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2344 case kConsStringTag | kAsciiStringTag:
2345 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002346 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002347 case kExternalStringTag | kAsciiStringTag:
2348 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2349 case kExternalStringTag | kTwoByteStringTag:
2350 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002351 case kSlicedStringTag | kAsciiStringTag:
2352 case kSlicedStringTag | kTwoByteStringTag:
2353 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002354 default:
2355 break;
2356 }
2357
2358 UNREACHABLE();
2359 return 0;
2360}
2361
2362
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002363void String::Set(int index, uint16_t value) {
2364 ASSERT(index >= 0 && index < length());
2365 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002366
ager@chromium.org5ec48922009-05-05 07:25:34 +00002367 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002368 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2369 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002370}
2371
2372
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002373bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002374 if (!StringShape(this).IsCons()) return true;
2375 return ConsString::cast(this)->second()->length() == 0;
2376}
2377
2378
2379String* String::GetUnderlying() {
2380 // Giving direct access to underlying string only makes sense if the
2381 // wrapping string is already flattened.
2382 ASSERT(this->IsFlat());
2383 ASSERT(StringShape(this).IsIndirect());
2384 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2385 const int kUnderlyingOffset = SlicedString::kParentOffset;
2386 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002387}
2388
2389
ager@chromium.org7c537e22008-10-16 08:43:32 +00002390uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002391 ASSERT(index >= 0 && index < length());
2392 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2393}
2394
2395
ager@chromium.org7c537e22008-10-16 08:43:32 +00002396void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002397 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2398 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2399 static_cast<byte>(value));
2400}
2401
2402
ager@chromium.org7c537e22008-10-16 08:43:32 +00002403Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002404 return FIELD_ADDR(this, kHeaderSize);
2405}
2406
2407
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002408char* SeqAsciiString::GetChars() {
2409 return reinterpret_cast<char*>(GetCharsAddress());
2410}
2411
2412
ager@chromium.org7c537e22008-10-16 08:43:32 +00002413Address SeqTwoByteString::GetCharsAddress() {
2414 return FIELD_ADDR(this, kHeaderSize);
2415}
2416
2417
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002418uc16* SeqTwoByteString::GetChars() {
2419 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2420}
2421
2422
ager@chromium.org7c537e22008-10-16 08:43:32 +00002423uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002424 ASSERT(index >= 0 && index < length());
2425 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2426}
2427
2428
ager@chromium.org7c537e22008-10-16 08:43:32 +00002429void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002430 ASSERT(index >= 0 && index < length());
2431 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2432}
2433
2434
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002435int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002436 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002437}
2438
2439
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002440int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002441 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002442}
2443
2444
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002445String* SlicedString::parent() {
2446 return String::cast(READ_FIELD(this, kParentOffset));
2447}
2448
2449
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002450void SlicedString::set_parent(String* parent, WriteBarrierMode mode) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002451 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002452 WRITE_FIELD(this, kParentOffset, parent);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002453 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kParentOffset, parent, mode);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002454}
2455
2456
2457SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2458
2459
ager@chromium.org870a0b62008-11-04 11:43:05 +00002460String* ConsString::first() {
2461 return String::cast(READ_FIELD(this, kFirstOffset));
2462}
2463
2464
2465Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002466 return READ_FIELD(this, kFirstOffset);
2467}
2468
2469
ager@chromium.org870a0b62008-11-04 11:43:05 +00002470void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002471 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002472 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002473}
2474
2475
ager@chromium.org870a0b62008-11-04 11:43:05 +00002476String* ConsString::second() {
2477 return String::cast(READ_FIELD(this, kSecondOffset));
2478}
2479
2480
2481Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002482 return READ_FIELD(this, kSecondOffset);
2483}
2484
2485
ager@chromium.org870a0b62008-11-04 11:43:05 +00002486void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002487 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002488 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002489}
2490
2491
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002492bool ExternalString::is_short() {
2493 InstanceType type = map()->instance_type();
2494 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002495}
2496
2497
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002498const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002499 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2500}
2501
2502
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002503void ExternalAsciiString::update_data_cache() {
2504 if (is_short()) return;
2505 const char** data_field =
2506 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2507 *data_field = resource()->data();
2508}
2509
2510
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002511void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002512 const ExternalAsciiString::Resource* resource) {
2513 *reinterpret_cast<const Resource**>(
2514 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002515 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002516}
2517
2518
2519const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002520 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002521}
2522
2523
2524uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2525 ASSERT(index >= 0 && index < length());
2526 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002527}
2528
2529
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002530const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002531 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2532}
2533
2534
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002535void ExternalTwoByteString::update_data_cache() {
2536 if (is_short()) return;
2537 const uint16_t** data_field =
2538 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2539 *data_field = resource()->data();
2540}
2541
2542
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002543void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002544 const ExternalTwoByteString::Resource* resource) {
2545 *reinterpret_cast<const Resource**>(
2546 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002547 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002548}
2549
2550
2551const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002552 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002553}
2554
2555
2556uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2557 ASSERT(index >= 0 && index < length());
2558 return GetChars()[index];
2559}
2560
2561
2562const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2563 unsigned start) {
2564 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002565}
2566
2567
ager@chromium.orgac091b72010-05-05 07:34:42 +00002568void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002569 set_finger_index(kEntriesIndex);
2570 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002571}
2572
2573
2574void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002575 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002576 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002577 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002578 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002579 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002580 MakeZeroSize();
2581}
2582
2583
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002584int JSFunctionResultCache::size() {
2585 return Smi::cast(get(kCacheSizeIndex))->value();
2586}
2587
2588
2589void JSFunctionResultCache::set_size(int size) {
2590 set(kCacheSizeIndex, Smi::FromInt(size));
2591}
2592
2593
2594int JSFunctionResultCache::finger_index() {
2595 return Smi::cast(get(kFingerIndex))->value();
2596}
2597
2598
2599void JSFunctionResultCache::set_finger_index(int finger_index) {
2600 set(kFingerIndex, Smi::FromInt(finger_index));
2601}
2602
2603
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002604byte ByteArray::get(int index) {
2605 ASSERT(index >= 0 && index < this->length());
2606 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2607}
2608
2609
2610void ByteArray::set(int index, byte value) {
2611 ASSERT(index >= 0 && index < this->length());
2612 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2613}
2614
2615
2616int ByteArray::get_int(int index) {
2617 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2618 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2619}
2620
2621
2622ByteArray* ByteArray::FromDataStartAddress(Address address) {
2623 ASSERT_TAG_ALIGNED(address);
2624 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2625}
2626
2627
2628Address ByteArray::GetDataStartAddress() {
2629 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2630}
2631
2632
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002633uint8_t* ExternalPixelArray::external_pixel_pointer() {
2634 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002635}
2636
2637
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002638uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002639 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002640 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002641 return ptr[index];
2642}
2643
2644
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002645MaybeObject* ExternalPixelArray::get(int index) {
2646 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2647}
2648
2649
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002650void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002651 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002652 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002653 ptr[index] = value;
2654}
2655
2656
ager@chromium.org3811b432009-10-28 14:53:37 +00002657void* ExternalArray::external_pointer() {
2658 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2659 return reinterpret_cast<void*>(ptr);
2660}
2661
2662
2663void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2664 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2665 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2666}
2667
2668
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002669int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002670 ASSERT((index >= 0) && (index < this->length()));
2671 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2672 return ptr[index];
2673}
2674
2675
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002676MaybeObject* ExternalByteArray::get(int index) {
2677 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2678}
2679
2680
ager@chromium.org3811b432009-10-28 14:53:37 +00002681void ExternalByteArray::set(int index, int8_t value) {
2682 ASSERT((index >= 0) && (index < this->length()));
2683 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2684 ptr[index] = value;
2685}
2686
2687
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002688uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002689 ASSERT((index >= 0) && (index < this->length()));
2690 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2691 return ptr[index];
2692}
2693
2694
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002695MaybeObject* ExternalUnsignedByteArray::get(int index) {
2696 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2697}
2698
2699
ager@chromium.org3811b432009-10-28 14:53:37 +00002700void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2701 ASSERT((index >= 0) && (index < this->length()));
2702 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2703 ptr[index] = value;
2704}
2705
2706
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002707int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002708 ASSERT((index >= 0) && (index < this->length()));
2709 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2710 return ptr[index];
2711}
2712
2713
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002714MaybeObject* ExternalShortArray::get(int index) {
2715 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2716}
2717
2718
ager@chromium.org3811b432009-10-28 14:53:37 +00002719void ExternalShortArray::set(int index, int16_t value) {
2720 ASSERT((index >= 0) && (index < this->length()));
2721 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2722 ptr[index] = value;
2723}
2724
2725
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002726uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002727 ASSERT((index >= 0) && (index < this->length()));
2728 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2729 return ptr[index];
2730}
2731
2732
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002733MaybeObject* ExternalUnsignedShortArray::get(int index) {
2734 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2735}
2736
2737
ager@chromium.org3811b432009-10-28 14:53:37 +00002738void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2739 ASSERT((index >= 0) && (index < this->length()));
2740 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2741 ptr[index] = value;
2742}
2743
2744
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002745int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002746 ASSERT((index >= 0) && (index < this->length()));
2747 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2748 return ptr[index];
2749}
2750
2751
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002752MaybeObject* ExternalIntArray::get(int index) {
2753 return GetHeap()->NumberFromInt32(get_scalar(index));
2754}
2755
2756
ager@chromium.org3811b432009-10-28 14:53:37 +00002757void ExternalIntArray::set(int index, int32_t value) {
2758 ASSERT((index >= 0) && (index < this->length()));
2759 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2760 ptr[index] = value;
2761}
2762
2763
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002764uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002765 ASSERT((index >= 0) && (index < this->length()));
2766 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2767 return ptr[index];
2768}
2769
2770
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002771MaybeObject* ExternalUnsignedIntArray::get(int index) {
2772 return GetHeap()->NumberFromUint32(get_scalar(index));
2773}
2774
2775
ager@chromium.org3811b432009-10-28 14:53:37 +00002776void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2777 ASSERT((index >= 0) && (index < this->length()));
2778 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2779 ptr[index] = value;
2780}
2781
2782
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002783float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002784 ASSERT((index >= 0) && (index < this->length()));
2785 float* ptr = static_cast<float*>(external_pointer());
2786 return ptr[index];
2787}
2788
2789
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002790MaybeObject* ExternalFloatArray::get(int index) {
2791 return GetHeap()->NumberFromDouble(get_scalar(index));
2792}
2793
2794
ager@chromium.org3811b432009-10-28 14:53:37 +00002795void ExternalFloatArray::set(int index, float value) {
2796 ASSERT((index >= 0) && (index < this->length()));
2797 float* ptr = static_cast<float*>(external_pointer());
2798 ptr[index] = value;
2799}
2800
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002801
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002802double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002803 ASSERT((index >= 0) && (index < this->length()));
2804 double* ptr = static_cast<double*>(external_pointer());
2805 return ptr[index];
2806}
2807
2808
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002809MaybeObject* ExternalDoubleArray::get(int index) {
2810 return GetHeap()->NumberFromDouble(get_scalar(index));
2811}
2812
2813
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002814void ExternalDoubleArray::set(int index, double value) {
2815 ASSERT((index >= 0) && (index < this->length()));
2816 double* ptr = static_cast<double*>(external_pointer());
2817 ptr[index] = value;
2818}
2819
2820
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002821int Map::visitor_id() {
2822 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2823}
2824
2825
2826void Map::set_visitor_id(int id) {
2827 ASSERT(0 <= id && id < 256);
2828 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2829}
2830
ager@chromium.org3811b432009-10-28 14:53:37 +00002831
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002832int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002833 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2834}
2835
2836
2837int Map::inobject_properties() {
2838 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002839}
2840
2841
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002842int Map::pre_allocated_property_fields() {
2843 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2844}
2845
2846
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002847int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002848 int instance_size = map->instance_size();
2849 if (instance_size != kVariableSizeSentinel) return instance_size;
2850 // We can ignore the "symbol" bit becase it is only set for symbols
2851 // and implies a string type.
2852 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002853 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002854 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002855 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002856 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002857 if (instance_type == ASCII_STRING_TYPE) {
2858 return SeqAsciiString::SizeFor(
2859 reinterpret_cast<SeqAsciiString*>(this)->length());
2860 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002861 if (instance_type == BYTE_ARRAY_TYPE) {
2862 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2863 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002864 if (instance_type == FREE_SPACE_TYPE) {
2865 return reinterpret_cast<FreeSpace*>(this)->size();
2866 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002867 if (instance_type == STRING_TYPE) {
2868 return SeqTwoByteString::SizeFor(
2869 reinterpret_cast<SeqTwoByteString*>(this)->length());
2870 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002871 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2872 return FixedDoubleArray::SizeFor(
2873 reinterpret_cast<FixedDoubleArray*>(this)->length());
2874 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002875 ASSERT(instance_type == CODE_TYPE);
2876 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002877}
2878
2879
2880void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002881 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002882 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002883 ASSERT(0 <= value && value < 256);
2884 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2885}
2886
2887
ager@chromium.org7c537e22008-10-16 08:43:32 +00002888void Map::set_inobject_properties(int value) {
2889 ASSERT(0 <= value && value < 256);
2890 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2891}
2892
2893
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002894void Map::set_pre_allocated_property_fields(int value) {
2895 ASSERT(0 <= value && value < 256);
2896 WRITE_BYTE_FIELD(this,
2897 kPreAllocatedPropertyFieldsOffset,
2898 static_cast<byte>(value));
2899}
2900
2901
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002902InstanceType Map::instance_type() {
2903 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2904}
2905
2906
2907void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002908 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2909}
2910
2911
2912int Map::unused_property_fields() {
2913 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2914}
2915
2916
2917void Map::set_unused_property_fields(int value) {
2918 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2919}
2920
2921
2922byte Map::bit_field() {
2923 return READ_BYTE_FIELD(this, kBitFieldOffset);
2924}
2925
2926
2927void Map::set_bit_field(byte value) {
2928 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2929}
2930
2931
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002932byte Map::bit_field2() {
2933 return READ_BYTE_FIELD(this, kBitField2Offset);
2934}
2935
2936
2937void Map::set_bit_field2(byte value) {
2938 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2939}
2940
2941
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002942void Map::set_non_instance_prototype(bool value) {
2943 if (value) {
2944 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2945 } else {
2946 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2947 }
2948}
2949
2950
2951bool Map::has_non_instance_prototype() {
2952 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2953}
2954
2955
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002956void Map::set_function_with_prototype(bool value) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002957 set_bit_field3(FunctionWithPrototype::update(bit_field3(), value));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002958}
2959
2960
2961bool Map::function_with_prototype() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002962 return FunctionWithPrototype::decode(bit_field3());
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002963}
2964
2965
ager@chromium.org870a0b62008-11-04 11:43:05 +00002966void Map::set_is_access_check_needed(bool access_check_needed) {
2967 if (access_check_needed) {
2968 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2969 } else {
2970 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2971 }
2972}
2973
2974
2975bool Map::is_access_check_needed() {
2976 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2977}
2978
2979
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002980void Map::set_is_extensible(bool value) {
2981 if (value) {
2982 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2983 } else {
2984 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2985 }
2986}
2987
2988bool Map::is_extensible() {
2989 return ((1 << kIsExtensible) & bit_field2()) != 0;
2990}
2991
2992
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002993void Map::set_attached_to_shared_function_info(bool value) {
2994 if (value) {
2995 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2996 } else {
2997 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2998 }
2999}
3000
3001bool Map::attached_to_shared_function_info() {
3002 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
3003}
3004
3005
3006void Map::set_is_shared(bool value) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003007 set_bit_field3(IsShared::update(bit_field3(), value));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003008}
3009
3010bool Map::is_shared() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003011 return IsShared::decode(bit_field3());
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003012}
3013
3014
3015JSFunction* Map::unchecked_constructor() {
3016 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
3017}
3018
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003019
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003020Code::Flags Code::flags() {
3021 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
3022}
3023
3024
3025void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003026 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003027 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003028 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
3029 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003030 ExtractArgumentsCountFromFlags(flags) >= 0);
3031 WRITE_INT_FIELD(this, kFlagsOffset, flags);
3032}
3033
3034
3035Code::Kind Code::kind() {
3036 return ExtractKindFromFlags(flags());
3037}
3038
3039
kasper.lund7276f142008-07-30 08:49:36 +00003040InlineCacheState Code::ic_state() {
3041 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003042 // Only allow uninitialized or debugger states for non-IC code
3043 // objects. This is used in the debugger to determine whether or not
3044 // a call to code object has been replaced with a debug break call.
3045 ASSERT(is_inline_cache_stub() ||
3046 result == UNINITIALIZED ||
3047 result == DEBUG_BREAK ||
3048 result == DEBUG_PREPARE_STEP_IN);
3049 return result;
3050}
3051
3052
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003053Code::ExtraICState Code::extra_ic_state() {
3054 ASSERT(is_inline_cache_stub());
3055 return ExtractExtraICStateFromFlags(flags());
3056}
3057
3058
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003059Code::StubType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003060 return ExtractTypeFromFlags(flags());
3061}
3062
3063
3064int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003065 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003066 return ExtractArgumentsCountFromFlags(flags());
3067}
3068
3069
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003070int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003071 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003072 kind() == UNARY_OP_IC ||
3073 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003074 kind() == COMPARE_IC ||
3075 kind() == TO_BOOLEAN_IC);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003076 return StubMajorKeyField::decode(
3077 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasper.lund7276f142008-07-30 08:49:36 +00003078}
3079
3080
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003081void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003082 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003083 kind() == UNARY_OP_IC ||
3084 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003085 kind() == COMPARE_IC ||
3086 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00003087 ASSERT(0 <= major && major < 256);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003088 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3089 int updated = StubMajorKeyField::update(previous, major);
3090 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003091}
3092
3093
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003094bool Code::is_pregenerated() {
3095 return kind() == STUB && IsPregeneratedField::decode(flags());
3096}
3097
3098
3099void Code::set_is_pregenerated(bool value) {
3100 ASSERT(kind() == STUB);
3101 Flags f = flags();
3102 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3103 set_flags(f);
3104}
3105
3106
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003107bool Code::optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003108 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003109 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3110}
3111
3112
3113void Code::set_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003114 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003115 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3116}
3117
3118
3119bool Code::has_deoptimization_support() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003120 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003121 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3122 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003123}
3124
3125
3126void Code::set_has_deoptimization_support(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003127 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003128 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3129 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3130 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3131}
3132
3133
3134bool Code::has_debug_break_slots() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003135 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003136 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3137 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3138}
3139
3140
3141void Code::set_has_debug_break_slots(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003142 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003143 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3144 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3145 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003146}
3147
3148
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003149bool Code::is_compiled_optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003150 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003151 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3152 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3153}
3154
3155
3156void Code::set_compiled_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003157 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003158 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3159 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3160 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3161}
3162
3163
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003164int Code::allow_osr_at_loop_nesting_level() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003165 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003166 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3167}
3168
3169
3170void Code::set_allow_osr_at_loop_nesting_level(int level) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003171 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003172 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3173 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3174}
3175
3176
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003177int Code::profiler_ticks() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003178 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003179 return READ_BYTE_FIELD(this, kProfilerTicksOffset);
3180}
3181
3182
3183void Code::set_profiler_ticks(int ticks) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003184 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003185 ASSERT(ticks < 256);
3186 WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
3187}
3188
3189
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003190unsigned Code::stack_slots() {
3191 ASSERT(kind() == OPTIMIZED_FUNCTION);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003192 return StackSlotsField::decode(
3193 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003194}
3195
3196
3197void Code::set_stack_slots(unsigned slots) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003198 CHECK(slots <= (1 << kStackSlotsBitCount));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003199 ASSERT(kind() == OPTIMIZED_FUNCTION);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003200 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3201 int updated = StackSlotsField::update(previous, slots);
3202 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003203}
3204
3205
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003206unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003207 ASSERT(kind() == OPTIMIZED_FUNCTION);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003208 return SafepointTableOffsetField::decode(
3209 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003210}
3211
3212
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003213void Code::set_safepoint_table_offset(unsigned offset) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003214 CHECK(offset <= (1 << kSafepointTableOffsetBitCount));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003215 ASSERT(kind() == OPTIMIZED_FUNCTION);
3216 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003217 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3218 int updated = SafepointTableOffsetField::update(previous, offset);
3219 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003220}
3221
3222
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003223unsigned Code::stack_check_table_offset() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003224 ASSERT_EQ(FUNCTION, kind());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003225 return StackCheckTableOffsetField::decode(
3226 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003227}
3228
3229
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003230void Code::set_stack_check_table_offset(unsigned offset) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003231 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003232 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003233 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3234 int updated = StackCheckTableOffsetField::update(previous, offset);
3235 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003236}
3237
3238
3239CheckType Code::check_type() {
3240 ASSERT(is_call_stub() || is_keyed_call_stub());
3241 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3242 return static_cast<CheckType>(type);
3243}
3244
3245
3246void Code::set_check_type(CheckType value) {
3247 ASSERT(is_call_stub() || is_keyed_call_stub());
3248 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3249}
3250
3251
danno@chromium.org40cb8782011-05-25 07:58:50 +00003252byte Code::unary_op_type() {
3253 ASSERT(is_unary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003254 return UnaryOpTypeField::decode(
3255 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003256}
3257
3258
danno@chromium.org40cb8782011-05-25 07:58:50 +00003259void Code::set_unary_op_type(byte value) {
3260 ASSERT(is_unary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003261 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3262 int updated = UnaryOpTypeField::update(previous, value);
3263 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003264}
3265
3266
danno@chromium.org40cb8782011-05-25 07:58:50 +00003267byte Code::binary_op_type() {
3268 ASSERT(is_binary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003269 return BinaryOpTypeField::decode(
3270 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003271}
3272
3273
danno@chromium.org40cb8782011-05-25 07:58:50 +00003274void Code::set_binary_op_type(byte value) {
3275 ASSERT(is_binary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003276 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3277 int updated = BinaryOpTypeField::update(previous, value);
3278 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003279}
3280
3281
danno@chromium.org40cb8782011-05-25 07:58:50 +00003282byte Code::binary_op_result_type() {
3283 ASSERT(is_binary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003284 return BinaryOpResultTypeField::decode(
3285 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003286}
3287
3288
danno@chromium.org40cb8782011-05-25 07:58:50 +00003289void Code::set_binary_op_result_type(byte value) {
3290 ASSERT(is_binary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003291 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3292 int updated = BinaryOpResultTypeField::update(previous, value);
3293 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003294}
3295
3296
3297byte Code::compare_state() {
3298 ASSERT(is_compare_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003299 return CompareStateField::decode(
3300 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003301}
3302
3303
3304void Code::set_compare_state(byte value) {
3305 ASSERT(is_compare_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003306 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3307 int updated = CompareStateField::update(previous, value);
3308 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003309}
3310
3311
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003312byte Code::compare_operation() {
3313 ASSERT(is_compare_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003314 return CompareOperationField::decode(
3315 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003316}
3317
3318
3319void Code::set_compare_operation(byte value) {
3320 ASSERT(is_compare_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003321 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3322 int updated = CompareOperationField::update(previous, value);
3323 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003324}
3325
3326
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003327byte Code::to_boolean_state() {
3328 ASSERT(is_to_boolean_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003329 return ToBooleanStateField::decode(
3330 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003331}
3332
3333
3334void Code::set_to_boolean_state(byte value) {
3335 ASSERT(is_to_boolean_ic_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003336 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3337 int updated = ToBooleanStateField::update(previous, value);
3338 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003339}
3340
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003341
3342bool Code::has_function_cache() {
3343 ASSERT(kind() == STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003344 return HasFunctionCacheField::decode(
3345 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003346}
3347
3348
3349void Code::set_has_function_cache(bool flag) {
3350 ASSERT(kind() == STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003351 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3352 int updated = HasFunctionCacheField::update(previous, flag);
3353 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003354}
3355
3356
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003357bool Code::is_inline_cache_stub() {
3358 Kind kind = this->kind();
3359 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3360}
3361
3362
3363Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003364 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003365 ExtraICState extra_ic_state,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003366 StubType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003367 int argc,
3368 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003369 // Extra IC state is only allowed for call IC stubs or for store IC
3370 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003371 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003372 kind == CALL_IC ||
3373 kind == STORE_IC ||
3374 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003375 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003376 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003377 | ICStateField::encode(ic_state)
3378 | TypeField::encode(type)
3379 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003380 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003381 | CacheHolderField::encode(holder);
3382 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003383}
3384
3385
3386Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003387 StubType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003388 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003389 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003390 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003391 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003392}
3393
3394
3395Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003396 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003397}
3398
3399
kasper.lund7276f142008-07-30 08:49:36 +00003400InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003401 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003402}
3403
3404
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003405Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003406 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003407}
3408
3409
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003410Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003411 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003412}
3413
3414
3415int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003416 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003417}
3418
3419
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003420InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003421 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003422}
3423
3424
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003425Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003426 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003427 return static_cast<Flags>(bits);
3428}
3429
3430
ager@chromium.org8bb60582008-12-11 12:02:20 +00003431Code* Code::GetCodeFromTargetAddress(Address address) {
3432 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3433 // GetCodeFromTargetAddress might be called when marking objects during mark
3434 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3435 // Code::cast. Code::cast does not work when the object's map is
3436 // marked.
3437 Code* result = reinterpret_cast<Code*>(code);
3438 return result;
3439}
3440
3441
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003442Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3443 return HeapObject::
3444 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3445}
3446
3447
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003448Object* Map::prototype() {
3449 return READ_FIELD(this, kPrototypeOffset);
3450}
3451
3452
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003453void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003454 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003455 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003456 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003457}
3458
3459
danno@chromium.org40cb8782011-05-25 07:58:50 +00003460DescriptorArray* Map::instance_descriptors() {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003461 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset);
3462 if (!object->IsDescriptorArray()) {
3463 ASSERT(object->IsMap() || object->IsUndefined());
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003464 return GetHeap()->empty_descriptor_array();
danno@chromium.org40cb8782011-05-25 07:58:50 +00003465 } else {
3466 return DescriptorArray::cast(object);
3467 }
3468}
3469
3470
danno@chromium.org40cb8782011-05-25 07:58:50 +00003471void Map::set_instance_descriptors(DescriptorArray* value,
3472 WriteBarrierMode mode) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003473 Heap* heap = GetHeap();
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003474
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003475 if (value == heap->empty_descriptor_array()) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003476 ClearDescriptorArray(heap, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003477 return;
danno@chromium.org40cb8782011-05-25 07:58:50 +00003478 }
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003479
3480 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset);
3481
3482 if (object->IsDescriptorArray()) {
3483 value->set_back_pointer_storage(
3484 DescriptorArray::cast(object)->back_pointer_storage());
3485 } else {
3486 ASSERT(object->IsMap() || object->IsUndefined());
3487 value->set_back_pointer_storage(object);
3488 }
3489
danno@chromium.org40cb8782011-05-25 07:58:50 +00003490 ASSERT(!is_shared());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003491 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003492 CONDITIONAL_WRITE_BARRIER(
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003493 heap, this, kInstanceDescriptorsOrBackPointerOffset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003494}
3495
3496
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003497void Map::InitializeDescriptors(DescriptorArray* descriptors) {
3498 int len = descriptors->number_of_descriptors();
3499 ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors);
3500 SLOW_ASSERT(descriptors->IsSortedNoDuplicates());
3501
3502#ifdef DEBUG
3503 bool used_indices[DescriptorArray::kMaxNumberOfDescriptors];
3504 for (int i = 0; i < len; ++i) used_indices[i] = false;
3505
3506 // Ensure that all enumeration indexes between 1 and length occur uniquely in
3507 // the descriptor array.
3508 for (int i = 0; i < len; ++i) {
3509 int enum_index = descriptors->GetDetails(i).index() -
3510 PropertyDetails::kInitialIndex;
3511 ASSERT(0 <= enum_index && enum_index < len);
3512 ASSERT(!used_indices[enum_index]);
3513 used_indices[enum_index] = true;
3514 }
3515#endif
3516
3517 set_instance_descriptors(descriptors);
3518
3519 for (int i = 0; i < len; ++i) {
3520 if (descriptors->GetDetails(i).index() == len) {
3521 SetLastAdded(i);
3522 break;
3523 }
3524 }
3525
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +00003526 ASSERT((len == 0 && LastAdded() == kNoneAdded) ||
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003527 len == descriptors->GetDetails(LastAdded()).index());
3528}
3529
3530
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003531SMI_ACCESSORS(Map, bit_field3, kBitField3Offset)
danno@chromium.org40cb8782011-05-25 07:58:50 +00003532
3533
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003534void Map::ClearDescriptorArray(Heap* heap, WriteBarrierMode mode) {
3535 Object* back_pointer = GetBackPointer();
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003536#ifdef DEBUG
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003537 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset);
3538 if (object->IsDescriptorArray()) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003539 ZapTransitions();
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003540 } else {
3541 ASSERT(object->IsMap() || object->IsUndefined());
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003542 }
3543#endif
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003544 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, back_pointer);
3545 CONDITIONAL_WRITE_BARRIER(
3546 heap, this, kInstanceDescriptorsOrBackPointerOffset, back_pointer, mode);
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003547}
3548
3549
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003550void Map::AppendDescriptor(Descriptor* desc,
3551 const DescriptorArray::WhitenessWitness& witness) {
3552 DescriptorArray* descriptors = instance_descriptors();
3553 int set_descriptors = NumberOfSetDescriptors();
3554 int new_last_added = descriptors->Append(desc, witness, set_descriptors);
3555 SetLastAdded(new_last_added);
3556}
3557
danno@chromium.org40cb8782011-05-25 07:58:50 +00003558
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003559Object* Map::GetBackPointer() {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003560 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset);
3561 if (object->IsDescriptorArray()) {
3562 return DescriptorArray::cast(object)->back_pointer_storage();
3563 } else {
3564 ASSERT(object->IsMap() || object->IsUndefined());
3565 return object;
3566 }
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003567}
3568
3569
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003570bool Map::HasElementsTransition() {
3571 return HasTransitionArray() && transitions()->HasElementsTransition();
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003572}
3573
3574
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003575bool Map::HasTransitionArray() {
3576 return instance_descriptors()->HasTransitionArray();
3577}
3578
3579
3580Map* Map::elements_transition_map() {
3581 return transitions()->elements_transition();
3582}
3583
3584
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +00003585bool Map::CanHaveMoreTransitions() {
3586 if (!HasTransitionArray()) return true;
3587 return FixedArray::SizeFor(transitions()->length() +
3588 TransitionArray::kTransitionSize)
3589 <= Page::kMaxNonCodeHeapObjectSize;
3590}
3591
3592
verwaest@chromium.org753aee42012-07-17 16:15:42 +00003593MaybeObject* Map::AddTransition(String* key, Map* target) {
3594 if (HasTransitionArray()) return transitions()->CopyInsert(key, target);
3595 return TransitionArray::NewWith(key, target);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003596}
3597
verwaest@chromium.org753aee42012-07-17 16:15:42 +00003598
3599void Map::SetTransition(int transition_index, Map* target) {
3600 transitions()->SetTarget(transition_index, target);
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00003601}
3602
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003603
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003604// If the map is using the empty descriptor array, install a new empty
3605// descriptor array that will contain an elements transition.
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003606static MaybeObject* AllowTransitions(Map* map) {
3607 if (map->instance_descriptors()->MayContainTransitions()) return map;
3608 DescriptorArray* descriptors;
3609 MaybeObject* maybe_descriptors =
3610 DescriptorArray::Allocate(0, DescriptorArray::CANNOT_BE_SHARED);
3611 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
3612 map->set_instance_descriptors(descriptors);
3613 return descriptors;
3614}
3615
3616
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003617// If the descriptor is using the empty transition array, install a new empty
3618// transition array that will have place for an element transition.
3619static MaybeObject* EnsureHasTransitionArray(Map* map) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003620 if (map->HasTransitionArray()) return map;
3621
3622 AllowTransitions(map);
3623
3624 TransitionArray* transitions;
3625 MaybeObject* maybe_transitions = TransitionArray::Allocate(0);
3626 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
3627 MaybeObject* added_transitions = map->set_transitions(transitions);
3628 if (added_transitions->IsFailure()) return added_transitions;
3629 return transitions;
3630}
3631
3632
3633MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003634 MaybeObject* allow_elements = EnsureHasTransitionArray(this);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003635 if (allow_elements->IsFailure()) return allow_elements;
3636 transitions()->set_elements_transition(transitioned_map);
3637 return this;
3638}
3639
3640
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003641FixedArray* Map::GetPrototypeTransitions() {
3642 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
3643 if (!transitions()->HasPrototypeTransitions()) {
3644 return GetHeap()->empty_fixed_array();
3645 }
3646 return transitions()->GetPrototypeTransitions();
3647}
3648
3649
3650MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
3651 MaybeObject* allow_prototype = EnsureHasTransitionArray(this);
3652 if (allow_prototype->IsFailure()) return allow_prototype;
3653#ifdef DEBUG
3654 if (HasPrototypeTransitions()) {
3655 ASSERT(GetPrototypeTransitions() != proto_transitions);
3656 ZapPrototypeTransitions();
3657 }
3658#endif
3659 transitions()->SetPrototypeTransitions(proto_transitions);
3660 return this;
3661}
3662
3663
3664bool Map::HasPrototypeTransitions() {
3665 return HasTransitionArray() && transitions()->HasPrototypeTransitions();
3666}
3667
3668
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003669TransitionArray* Map::transitions() {
3670 return instance_descriptors()->transitions();
3671}
3672
3673
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003674void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003675#ifdef DEBUG
3676 ZapTransitions();
3677#endif
3678 DescriptorArray* descriptors = instance_descriptors();
3679 if (descriptors->number_of_descriptors() == 0) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003680 ClearDescriptorArray(heap, mode);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003681 } else {
3682 descriptors->ClearTransitions();
3683 }
3684}
3685
3686
3687MaybeObject* Map::set_transitions(TransitionArray* transitions_array) {
3688 MaybeObject* allow_transitions = AllowTransitions(this);
3689 if (allow_transitions->IsFailure()) return allow_transitions;
3690#ifdef DEBUG
3691 if (HasTransitionArray()) {
3692 ASSERT(transitions() != transitions_array);
3693 ZapTransitions();
3694 }
3695#endif
3696 instance_descriptors()->set_transitions(transitions_array);
3697 return this;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003698}
3699
3700
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003701void Map::init_back_pointer(Object* undefined) {
3702 ASSERT(undefined->IsUndefined());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003703 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, undefined);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003704}
3705
3706
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003707void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003708 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
3709 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
3710 (value->IsMap() && GetBackPointer()->IsUndefined()));
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003711 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset);
verwaest@chromium.org753aee42012-07-17 16:15:42 +00003712 if (object->IsDescriptorArray()) {
3713 DescriptorArray::cast(object)->set_back_pointer_storage(value);
3714 } else {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003715 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, value);
3716 CONDITIONAL_WRITE_BARRIER(
3717 GetHeap(), this, kInstanceDescriptorsOrBackPointerOffset, value, mode);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003718 }
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003719}
3720
3721
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003722// Can either be Smi (no transitions), normal transition array, or a transition
3723// array with the header overwritten as a Smi (thus iterating).
3724TransitionArray* Map::unchecked_transition_array() {
3725 ASSERT(HasTransitionArray());
3726 Object* object = *HeapObject::RawField(instance_descriptors(),
3727 DescriptorArray::kTransitionsOffset);
3728 ASSERT(!object->IsSmi());
3729 TransitionArray* transition_array = static_cast<TransitionArray*>(object);
3730 return transition_array;
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003731}
3732
3733
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003734HeapObject* Map::UncheckedPrototypeTransitions() {
3735 ASSERT(HasTransitionArray());
3736 ASSERT(unchecked_transition_array()->HasPrototypeTransitions());
3737 return unchecked_transition_array()->UncheckedPrototypeTransitions();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003738}
3739
3740
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003741ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003742ACCESSORS(Map, constructor, Object, kConstructorOffset)
3743
3744ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003745ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003746ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003747
3748ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3749ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003750ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003751
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003752ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003753
3754ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3755ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3756ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3757ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003758ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003759ACCESSORS(AccessorInfo, expected_receiver_type, Object,
3760 kExpectedReceiverTypeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003761
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003762ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3763ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3764
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003765ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3766ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3767ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3768
3769ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3770ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3771ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3772ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3773ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3774ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3775
3776ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3777ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3778
3779ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3780ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3781
3782ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3783ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003784ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3785 kPropertyAccessorsOffset)
3786ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3787 kPrototypeTemplateOffset)
3788ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3789ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3790 kNamedPropertyHandlerOffset)
3791ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3792 kIndexedPropertyHandlerOffset)
3793ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3794 kInstanceTemplateOffset)
3795ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3796ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003797ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3798 kInstanceCallHandlerOffset)
3799ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3800 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003801ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003802
3803ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003804ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3805 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003806
3807ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3808ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3809
3810ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3811
3812ACCESSORS(Script, source, Object, kSourceOffset)
3813ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003814ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003815ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
3816ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003817ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003818ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003819ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003820ACCESSORS_TO_SMI(Script, type, kTypeOffset)
3821ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
3822ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003823ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003824ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003825ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
3826 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003827
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003828#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003829ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3830ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3831ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3832ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3833
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003834ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
3835ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
3836ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003837ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003838#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003839
3840ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003841ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
3842 kOptimizedCodeMapOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003843ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3844ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003845ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3846 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003847ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003848ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3849ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003850ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003851ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3852 kThisPropertyAssignmentsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003853SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003854
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00003855
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003856BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3857 kHiddenPrototypeBit)
3858BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3859BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3860 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003861BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3862 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003863BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3864 kIsExpressionBit)
3865BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3866 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003867BOOL_GETTER(SharedFunctionInfo,
3868 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003869 has_only_simple_this_property_assignments,
3870 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003871BOOL_ACCESSORS(SharedFunctionInfo,
3872 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003873 allows_lazy_compilation,
3874 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003875BOOL_ACCESSORS(SharedFunctionInfo,
3876 compiler_hints,
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003877 allows_lazy_compilation_without_context,
3878 kAllowLazyCompilationWithoutContext)
3879BOOL_ACCESSORS(SharedFunctionInfo,
3880 compiler_hints,
whesse@chromium.org7b260152011-06-20 15:33:18 +00003881 uses_arguments,
3882 kUsesArguments)
3883BOOL_ACCESSORS(SharedFunctionInfo,
3884 compiler_hints,
3885 has_duplicate_parameters,
3886 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003887
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003888
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003889#if V8_HOST_ARCH_32_BIT
3890SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3891SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003892 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003893SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003894 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003895SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3896SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003897 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003898SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3899SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003900 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003901SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003902 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003903SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003904 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003905SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003906SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
3907SMI_ACCESSORS(SharedFunctionInfo,
3908 stress_deopt_counter,
3909 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003910#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003911
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003912#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003913 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003914 int holder::name() { \
3915 int value = READ_INT_FIELD(this, offset); \
3916 ASSERT(kHeapObjectTag == 1); \
3917 ASSERT((value & kHeapObjectTag) == 0); \
3918 return value >> 1; \
3919 } \
3920 void holder::set_##name(int value) { \
3921 ASSERT(kHeapObjectTag == 1); \
3922 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3923 (value & 0xC0000000) == 0x000000000); \
3924 WRITE_INT_FIELD(this, \
3925 offset, \
3926 (value << 1) & ~kHeapObjectTag); \
3927 }
3928
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003929#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3930 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003931 INT_ACCESSORS(holder, name, offset)
3932
3933
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003934PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003935PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3936 formal_parameter_count,
3937 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003938
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003939PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3940 expected_nof_properties,
3941 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003942PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3943
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003944PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3945PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3946 start_position_and_type,
3947 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003948
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003949PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3950 function_token_position,
3951 kFunctionTokenPositionOffset)
3952PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3953 compiler_hints,
3954 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003955
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003956PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3957 this_property_assignments_count,
3958 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003959PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003960
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003961PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, counters, kCountersOffset)
3962PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3963 stress_deopt_counter,
3964 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003965#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003966
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003967
3968int SharedFunctionInfo::construction_count() {
3969 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3970}
3971
3972
3973void SharedFunctionInfo::set_construction_count(int value) {
3974 ASSERT(0 <= value && value < 256);
3975 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3976}
3977
3978
whesse@chromium.org7b260152011-06-20 15:33:18 +00003979BOOL_ACCESSORS(SharedFunctionInfo,
3980 compiler_hints,
3981 live_objects_may_exist,
3982 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003983
3984
3985bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003986 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003987}
3988
3989
whesse@chromium.org7b260152011-06-20 15:33:18 +00003990BOOL_GETTER(SharedFunctionInfo,
3991 compiler_hints,
3992 optimization_disabled,
3993 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003994
3995
3996void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3997 set_compiler_hints(BooleanBit::set(compiler_hints(),
3998 kOptimizationDisabled,
3999 disable));
4000 // If disabling optimizations we reflect that in the code object so
4001 // it will not be counted as optimizable code.
4002 if ((code()->kind() == Code::FUNCTION) && disable) {
4003 code()->set_optimizable(false);
4004 }
4005}
4006
4007
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004008int SharedFunctionInfo::profiler_ticks() {
4009 if (code()->kind() != Code::FUNCTION) return 0;
4010 return code()->profiler_ticks();
4011}
4012
4013
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004014LanguageMode SharedFunctionInfo::language_mode() {
4015 int hints = compiler_hints();
4016 if (BooleanBit::get(hints, kExtendedModeFunction)) {
4017 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
4018 return EXTENDED_MODE;
4019 }
4020 return BooleanBit::get(hints, kStrictModeFunction)
4021 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004022}
4023
4024
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004025void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
4026 // We only allow language mode transitions that go set the same language mode
4027 // again or go up in the chain:
4028 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
4029 ASSERT(this->language_mode() == CLASSIC_MODE ||
4030 this->language_mode() == language_mode ||
4031 language_mode == EXTENDED_MODE);
4032 int hints = compiler_hints();
4033 hints = BooleanBit::set(
4034 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
4035 hints = BooleanBit::set(
4036 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
4037 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004038}
4039
4040
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004041bool SharedFunctionInfo::is_classic_mode() {
4042 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
4043}
4044
4045BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
4046 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004047BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
4048BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
4049 name_should_print_as_anonymous,
4050 kNameShouldPrintAsAnonymous)
4051BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
4052BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00004053BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
4054BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
4055 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00004056BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004057BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_cache, kDontCache)
whesse@chromium.org7b260152011-06-20 15:33:18 +00004058
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004059void SharedFunctionInfo::BeforeVisitingPointers() {
4060 if (IsInobjectSlackTrackingInProgress()) DetachInitialMap();
4061
4062 // Flush optimized code map on major GC.
4063 // Note: we may experiment with rebuilding it or retaining entries
4064 // which should survive as we iterate through optimized functions
4065 // anyway.
4066 set_optimized_code_map(Smi::FromInt(0));
4067}
4068
4069
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004070ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
4071ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
4072
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00004073ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
4074
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00004075bool Script::HasValidSource() {
4076 Object* src = this->source();
4077 if (!src->IsString()) return true;
4078 String* src_str = String::cast(src);
4079 if (!StringShape(src_str).IsExternal()) return true;
4080 if (src_str->IsAsciiRepresentation()) {
4081 return ExternalAsciiString::cast(src)->resource() != NULL;
4082 } else if (src_str->IsTwoByteRepresentation()) {
4083 return ExternalTwoByteString::cast(src)->resource() != NULL;
4084 }
4085 return true;
4086}
4087
4088
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00004089void SharedFunctionInfo::DontAdaptArguments() {
4090 ASSERT(code()->kind() == Code::BUILTIN);
4091 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
4092}
4093
4094
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004095int SharedFunctionInfo::start_position() {
4096 return start_position_and_type() >> kStartPositionShift;
4097}
4098
4099
4100void SharedFunctionInfo::set_start_position(int start_position) {
4101 set_start_position_and_type((start_position << kStartPositionShift)
4102 | (start_position_and_type() & ~kStartPositionMask));
4103}
4104
4105
4106Code* SharedFunctionInfo::code() {
4107 return Code::cast(READ_FIELD(this, kCodeOffset));
4108}
4109
4110
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004111Code* SharedFunctionInfo::unchecked_code() {
4112 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
4113}
4114
4115
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004116void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004117 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004118 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004119}
4120
4121
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004122ScopeInfo* SharedFunctionInfo::scope_info() {
4123 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00004124}
4125
4126
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004127void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00004128 WriteBarrierMode mode) {
4129 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004130 CONDITIONAL_WRITE_BARRIER(GetHeap(),
4131 this,
4132 kScopeInfoOffset,
4133 reinterpret_cast<Object*>(value),
4134 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00004135}
4136
4137
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004138bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004139 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004140 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004141}
4142
4143
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004144bool SharedFunctionInfo::IsApiFunction() {
4145 return function_data()->IsFunctionTemplateInfo();
4146}
4147
4148
4149FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
4150 ASSERT(IsApiFunction());
4151 return FunctionTemplateInfo::cast(function_data());
4152}
4153
4154
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004155bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00004156 return function_data()->IsSmi();
4157}
4158
4159
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004160BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
4161 ASSERT(HasBuiltinFunctionId());
4162 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004163}
4164
4165
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004166int SharedFunctionInfo::code_age() {
4167 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
4168}
4169
4170
4171void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00004172 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
4173 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004174}
4175
4176
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004177int SharedFunctionInfo::ic_age() {
4178 return ICAgeBits::decode(counters());
4179}
4180
4181
4182void SharedFunctionInfo::set_ic_age(int ic_age) {
4183 set_counters(ICAgeBits::update(counters(), ic_age));
4184}
4185
4186
4187int SharedFunctionInfo::deopt_count() {
4188 return DeoptCountBits::decode(counters());
4189}
4190
4191
4192void SharedFunctionInfo::set_deopt_count(int deopt_count) {
4193 set_counters(DeoptCountBits::update(counters(), deopt_count));
4194}
4195
4196
4197void SharedFunctionInfo::increment_deopt_count() {
4198 int value = counters();
4199 int deopt_count = DeoptCountBits::decode(value);
4200 deopt_count = (deopt_count + 1) & DeoptCountBits::kMax;
4201 set_counters(DeoptCountBits::update(value, deopt_count));
4202}
4203
4204
4205int SharedFunctionInfo::opt_reenable_tries() {
4206 return OptReenableTriesBits::decode(counters());
4207}
4208
4209
4210void SharedFunctionInfo::set_opt_reenable_tries(int tries) {
4211 set_counters(OptReenableTriesBits::update(counters(), tries));
4212}
4213
4214
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004215bool SharedFunctionInfo::has_deoptimization_support() {
4216 Code* code = this->code();
4217 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
4218}
4219
4220
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004221void SharedFunctionInfo::TryReenableOptimization() {
4222 int tries = opt_reenable_tries();
4223 set_opt_reenable_tries((tries + 1) & OptReenableTriesBits::kMax);
4224 // We reenable optimization whenever the number of tries is a large
4225 // enough power of 2.
4226 if (tries >= 16 && (((tries - 1) & tries) == 0)) {
4227 set_optimization_disabled(false);
4228 set_opt_count(0);
4229 set_deopt_count(0);
4230 code()->set_optimizable(true);
4231 }
4232}
4233
4234
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004235bool JSFunction::IsBuiltin() {
4236 return context()->global()->IsJSBuiltinsObject();
4237}
4238
4239
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004240bool JSFunction::NeedsArgumentsAdaption() {
4241 return shared()->formal_parameter_count() !=
4242 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
4243}
4244
4245
4246bool JSFunction::IsOptimized() {
4247 return code()->kind() == Code::OPTIMIZED_FUNCTION;
4248}
4249
4250
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00004251bool JSFunction::IsOptimizable() {
4252 return code()->kind() == Code::FUNCTION && code()->optimizable();
4253}
4254
4255
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004256bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004257 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004258}
4259
4260
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004261bool JSFunction::IsMarkedForParallelRecompilation() {
4262 return code() ==
4263 GetIsolate()->builtins()->builtin(Builtins::kParallelRecompile);
4264}
4265
4266
4267bool JSFunction::IsInRecompileQueue() {
4268 return code() == GetIsolate()->builtins()->builtin(
4269 Builtins::kInRecompileQueue);
4270}
4271
4272
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004273Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004274 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004275}
4276
4277
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004278Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004279 return reinterpret_cast<Code*>(
4280 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004281}
4282
4283
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004284void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004285 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004286 Address entry = value->entry();
4287 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004288 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
4289 this,
4290 HeapObject::RawField(this, kCodeEntryOffset),
4291 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004292}
4293
4294
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004295void JSFunction::ReplaceCode(Code* code) {
4296 bool was_optimized = IsOptimized();
4297 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
4298
4299 set_code(code);
4300
4301 // Add/remove the function from the list of optimized functions for this
4302 // context based on the state change.
4303 if (!was_optimized && is_optimized) {
4304 context()->global_context()->AddOptimizedFunction(this);
4305 }
4306 if (was_optimized && !is_optimized) {
4307 context()->global_context()->RemoveOptimizedFunction(this);
4308 }
4309}
4310
4311
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004312Context* JSFunction::context() {
4313 return Context::cast(READ_FIELD(this, kContextOffset));
4314}
4315
4316
4317Object* JSFunction::unchecked_context() {
4318 return READ_FIELD(this, kContextOffset);
4319}
4320
4321
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004322SharedFunctionInfo* JSFunction::unchecked_shared() {
4323 return reinterpret_cast<SharedFunctionInfo*>(
4324 READ_FIELD(this, kSharedFunctionInfoOffset));
4325}
4326
4327
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004328void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004329 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004330 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004331 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004332}
4333
4334ACCESSORS(JSFunction, prototype_or_initial_map, Object,
4335 kPrototypeOrInitialMapOffset)
4336
4337
4338Map* JSFunction::initial_map() {
4339 return Map::cast(prototype_or_initial_map());
4340}
4341
4342
4343void JSFunction::set_initial_map(Map* value) {
4344 set_prototype_or_initial_map(value);
4345}
4346
4347
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004348MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
4349 Map* initial_map) {
4350 Context* global_context = context()->global_context();
4351 Object* array_function =
4352 global_context->get(Context::ARRAY_FUNCTION_INDEX);
4353 if (array_function->IsJSFunction() &&
4354 this == JSFunction::cast(array_function)) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004355 // Replace all of the cached initial array maps in the global context with
4356 // the appropriate transitioned elements kind maps.
4357 Heap* heap = GetHeap();
4358 MaybeObject* maybe_maps =
4359 heap->AllocateFixedArrayWithHoles(kElementsKindCount);
4360 FixedArray* maps;
4361 if (!maybe_maps->To(&maps)) return maybe_maps;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004362
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004363 Map* current_map = initial_map;
4364 ElementsKind kind = current_map->elements_kind();
4365 ASSERT(kind == GetInitialFastElementsKind());
4366 maps->set(kind, current_map);
4367 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
4368 i < kFastElementsKindCount; ++i) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004369 Map* new_map;
4370 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
4371 MaybeObject* maybe_new_map =
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004372 current_map->CopyAsElementsKind(next_kind, INSERT_TRANSITION);
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004373 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
4374 maps->set(next_kind, new_map);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004375 current_map = new_map;
4376 }
4377 global_context->set_js_array_maps(maps);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004378 }
4379 set_initial_map(initial_map);
4380 return this;
4381}
4382
4383
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004384bool JSFunction::has_initial_map() {
4385 return prototype_or_initial_map()->IsMap();
4386}
4387
4388
4389bool JSFunction::has_instance_prototype() {
4390 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4391}
4392
4393
4394bool JSFunction::has_prototype() {
4395 return map()->has_non_instance_prototype() || has_instance_prototype();
4396}
4397
4398
4399Object* JSFunction::instance_prototype() {
4400 ASSERT(has_instance_prototype());
4401 if (has_initial_map()) return initial_map()->prototype();
4402 // When there is no initial map and the prototype is a JSObject, the
4403 // initial map field is used for the prototype field.
4404 return prototype_or_initial_map();
4405}
4406
4407
4408Object* JSFunction::prototype() {
4409 ASSERT(has_prototype());
4410 // If the function's prototype property has been set to a non-JSObject
4411 // value, that value is stored in the constructor field of the map.
4412 if (map()->has_non_instance_prototype()) return map()->constructor();
4413 return instance_prototype();
4414}
4415
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004416
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00004417bool JSFunction::should_have_prototype() {
4418 return map()->function_with_prototype();
4419}
4420
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004421
4422bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004423 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004424}
4425
4426
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004427FixedArray* JSFunction::literals() {
4428 ASSERT(!shared()->bound());
4429 return literals_or_bindings();
4430}
4431
4432
4433void JSFunction::set_literals(FixedArray* literals) {
4434 ASSERT(!shared()->bound());
4435 set_literals_or_bindings(literals);
4436}
4437
4438
4439FixedArray* JSFunction::function_bindings() {
4440 ASSERT(shared()->bound());
4441 return literals_or_bindings();
4442}
4443
4444
4445void JSFunction::set_function_bindings(FixedArray* bindings) {
4446 ASSERT(shared()->bound());
4447 // Bound function literal may be initialized to the empty fixed array
4448 // before the bindings are set.
4449 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4450 bindings->map() == GetHeap()->fixed_cow_array_map());
4451 set_literals_or_bindings(bindings);
4452}
4453
4454
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004455int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004456 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004457 return literals()->length();
4458}
4459
4460
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004461Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004462 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004463 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004464}
4465
4466
4467void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4468 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004469 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004470 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004471 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004472}
4473
4474
4475Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004476 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004477 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4478}
4479
4480
4481void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4482 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004483 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004484 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004485 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004486}
4487
4488
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004489ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004490ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004491ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4492ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4493
4494
4495void JSProxy::InitializeBody(int object_size, Object* value) {
4496 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4497 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4498 WRITE_FIELD(this, offset, value);
4499 }
4500}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004501
4502
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004503ACCESSORS(JSSet, table, Object, kTableOffset)
4504ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004505ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4506ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004507
4508
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004509Address Foreign::foreign_address() {
4510 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004511}
4512
4513
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004514void Foreign::set_foreign_address(Address value) {
4515 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004516}
4517
4518
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004519ACCESSORS(JSModule, context, Object, kContextOffset)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004520ACCESSORS(JSModule, scope_info, ScopeInfo, kScopeInfoOffset)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004521
4522
4523JSModule* JSModule::cast(Object* obj) {
4524 ASSERT(obj->IsJSModule());
4525 ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
4526 return reinterpret_cast<JSModule*>(obj);
4527}
4528
4529
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004530ACCESSORS(JSValue, value, Object, kValueOffset)
4531
4532
4533JSValue* JSValue::cast(Object* obj) {
4534 ASSERT(obj->IsJSValue());
4535 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4536 return reinterpret_cast<JSValue*>(obj);
4537}
4538
4539
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004540ACCESSORS(JSDate, value, Object, kValueOffset)
4541ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4542ACCESSORS(JSDate, year, Object, kYearOffset)
4543ACCESSORS(JSDate, month, Object, kMonthOffset)
4544ACCESSORS(JSDate, day, Object, kDayOffset)
4545ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4546ACCESSORS(JSDate, hour, Object, kHourOffset)
4547ACCESSORS(JSDate, min, Object, kMinOffset)
4548ACCESSORS(JSDate, sec, Object, kSecOffset)
4549
4550
4551JSDate* JSDate::cast(Object* obj) {
4552 ASSERT(obj->IsJSDate());
4553 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4554 return reinterpret_cast<JSDate*>(obj);
4555}
4556
4557
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004558ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4559ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4560ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4561ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4562ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4563SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4564SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4565
4566
4567JSMessageObject* JSMessageObject::cast(Object* obj) {
4568 ASSERT(obj->IsJSMessageObject());
4569 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4570 return reinterpret_cast<JSMessageObject*>(obj);
4571}
4572
4573
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004574INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004575ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004576ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004577ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004578ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004579ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00004580INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004581
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004582byte* Code::instruction_start() {
4583 return FIELD_ADDR(this, kHeaderSize);
4584}
4585
4586
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004587byte* Code::instruction_end() {
4588 return instruction_start() + instruction_size();
4589}
4590
4591
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004592int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004593 return RoundUp(instruction_size(), kObjectAlignment);
4594}
4595
4596
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004597FixedArray* Code::unchecked_deoptimization_data() {
4598 return reinterpret_cast<FixedArray*>(
4599 READ_FIELD(this, kDeoptimizationDataOffset));
4600}
4601
4602
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004603ByteArray* Code::unchecked_relocation_info() {
4604 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004605}
4606
4607
4608byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004609 return unchecked_relocation_info()->GetDataStartAddress();
4610}
4611
4612
4613int Code::relocation_size() {
4614 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004615}
4616
4617
4618byte* Code::entry() {
4619 return instruction_start();
4620}
4621
4622
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004623bool Code::contains(byte* inner_pointer) {
4624 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004625}
4626
4627
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004628ACCESSORS(JSArray, length, Object, kLengthOffset)
4629
4630
ager@chromium.org236ad962008-09-25 09:45:57 +00004631ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004632
4633
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004634JSRegExp::Type JSRegExp::TypeTag() {
4635 Object* data = this->data();
4636 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4637 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4638 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004639}
4640
4641
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004642JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4643 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4644 return static_cast<JSRegExp::Type>(smi->value());
4645}
4646
4647
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004648int JSRegExp::CaptureCount() {
4649 switch (TypeTag()) {
4650 case ATOM:
4651 return 0;
4652 case IRREGEXP:
4653 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4654 default:
4655 UNREACHABLE();
4656 return -1;
4657 }
4658}
4659
4660
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004661JSRegExp::Flags JSRegExp::GetFlags() {
4662 ASSERT(this->data()->IsFixedArray());
4663 Object* data = this->data();
4664 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4665 return Flags(smi->value());
4666}
4667
4668
4669String* JSRegExp::Pattern() {
4670 ASSERT(this->data()->IsFixedArray());
4671 Object* data = this->data();
4672 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4673 return pattern;
4674}
4675
4676
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004677Object* JSRegExp::DataAt(int index) {
4678 ASSERT(TypeTag() != NOT_COMPILED);
4679 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004680}
4681
4682
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004683Object* JSRegExp::DataAtUnchecked(int index) {
4684 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4685 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4686 return READ_FIELD(fa, offset);
4687}
4688
4689
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004690void JSRegExp::SetDataAt(int index, Object* value) {
4691 ASSERT(TypeTag() != NOT_COMPILED);
4692 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4693 FixedArray::cast(data())->set(index, value);
4694}
4695
4696
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004697void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4698 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4699 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4700 if (value->IsSmi()) {
4701 fa->set_unchecked(index, Smi::cast(value));
4702 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004703 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004704 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4705 }
4706}
4707
4708
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004709ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004710 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004711#if DEBUG
4712 FixedArrayBase* fixed_array =
4713 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4714 Map* map = fixed_array->map();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004715 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
4716 (map == GetHeap()->fixed_array_map() ||
4717 map == GetHeap()->fixed_cow_array_map())) ||
4718 (IsFastDoubleElementsKind(kind) &&
4719 (fixed_array->IsFixedDoubleArray() ||
4720 fixed_array == GetHeap()->empty_fixed_array())) ||
4721 (kind == DICTIONARY_ELEMENTS &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004722 fixed_array->IsFixedArray() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004723 fixed_array->IsDictionary()) ||
4724 (kind > DICTIONARY_ELEMENTS));
4725 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4726 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004727#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004728 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004729}
4730
4731
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004732ElementsAccessor* JSObject::GetElementsAccessor() {
4733 return ElementsAccessor::ForKind(GetElementsKind());
4734}
4735
4736
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004737bool JSObject::HasFastObjectElements() {
4738 return IsFastObjectElementsKind(GetElementsKind());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004739}
4740
4741
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004742bool JSObject::HasFastSmiElements() {
4743 return IsFastSmiElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004744}
4745
4746
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004747bool JSObject::HasFastSmiOrObjectElements() {
4748 return IsFastSmiOrObjectElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004749}
4750
4751
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004752bool JSObject::HasFastDoubleElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004753 return IsFastDoubleElementsKind(GetElementsKind());
4754}
4755
4756
4757bool JSObject::HasFastHoleyElements() {
4758 return IsFastHoleyElementsKind(GetElementsKind());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004759}
4760
4761
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004762bool JSObject::HasDictionaryElements() {
4763 return GetElementsKind() == DICTIONARY_ELEMENTS;
4764}
4765
4766
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004767bool JSObject::HasNonStrictArgumentsElements() {
4768 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4769}
4770
4771
ager@chromium.org3811b432009-10-28 14:53:37 +00004772bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004773 HeapObject* array = elements();
4774 ASSERT(array != NULL);
4775 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004776}
4777
4778
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004779#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4780bool JSObject::HasExternal##name##Elements() { \
4781 HeapObject* array = elements(); \
4782 ASSERT(array != NULL); \
4783 if (!array->IsHeapObject()) \
4784 return false; \
4785 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004786}
4787
4788
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004789EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4790EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4791EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4792EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4793 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4794EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4795EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4796 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4797EXTERNAL_ELEMENTS_CHECK(Float,
4798 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004799EXTERNAL_ELEMENTS_CHECK(Double,
4800 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004801EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004802
4803
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004804bool JSObject::HasNamedInterceptor() {
4805 return map()->has_named_interceptor();
4806}
4807
4808
4809bool JSObject::HasIndexedInterceptor() {
4810 return map()->has_indexed_interceptor();
4811}
4812
4813
lrn@chromium.org303ada72010-10-27 09:33:13 +00004814MaybeObject* JSObject::EnsureWritableFastElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004815 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004816 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004817 Isolate* isolate = GetIsolate();
4818 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004819 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004820 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4821 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004822 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4823 return maybe_writable_elems;
4824 }
4825 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004826 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004827 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004828 return writable_elems;
4829}
4830
4831
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004832StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004833 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004834 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004835}
4836
4837
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004838SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004839 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004840 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004841}
4842
4843
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004844bool String::IsHashFieldComputed(uint32_t field) {
4845 return (field & kHashNotComputedMask) == 0;
4846}
4847
4848
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004849bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004850 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004851}
4852
4853
4854uint32_t String::Hash() {
4855 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004856 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004857 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004858 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004859 return ComputeAndSetHash();
4860}
4861
4862
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004863StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004864 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004865 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004866 array_index_(0),
4867 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4868 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004869 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004870 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004871}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004872
4873
4874bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004875 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004876}
4877
4878
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004879void StringHasher::AddCharacter(uint32_t c) {
4880 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4881 AddSurrogatePair(c); // Not inlined.
4882 return;
4883 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004884 // Use the Jenkins one-at-a-time hash function to update the hash
4885 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004886 raw_running_hash_ += c;
4887 raw_running_hash_ += (raw_running_hash_ << 10);
4888 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004889 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004890 if (is_array_index_) {
4891 if (c < '0' || c > '9') {
4892 is_array_index_ = false;
4893 } else {
4894 int d = c - '0';
4895 if (is_first_char_) {
4896 is_first_char_ = false;
4897 if (c == '0' && length_ > 1) {
4898 is_array_index_ = false;
4899 return;
4900 }
4901 }
4902 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4903 is_array_index_ = false;
4904 } else {
4905 array_index_ = array_index_ * 10 + d;
4906 }
4907 }
4908 }
4909}
4910
4911
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004912void StringHasher::AddCharacterNoIndex(uint32_t c) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00004913 ASSERT(!is_array_index());
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004914 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4915 AddSurrogatePairNoIndex(c); // Not inlined.
4916 return;
4917 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004918 raw_running_hash_ += c;
4919 raw_running_hash_ += (raw_running_hash_ << 10);
4920 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4921}
4922
4923
4924uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004925 // Get the calculated raw hash value and do some more bit ops to distribute
4926 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004927 uint32_t result = raw_running_hash_;
4928 result += (result << 3);
4929 result ^= (result >> 11);
4930 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004931 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004932 result = 27;
4933 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004934 return result;
4935}
4936
4937
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004938template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004939uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4940 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004941 if (!hasher.has_trivial_hash()) {
4942 int i;
4943 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4944 hasher.AddCharacter(chars[i]);
4945 }
4946 for (; i < length; i++) {
4947 hasher.AddCharacterNoIndex(chars[i]);
4948 }
4949 }
4950 return hasher.GetHashField();
4951}
4952
4953
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004954bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004955 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004956 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4957 return false;
4958 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004959 return SlowAsArrayIndex(index);
4960}
4961
4962
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004963Object* JSReceiver::GetPrototype() {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004964 return map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004965}
4966
4967
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00004968Object* JSReceiver::GetConstructor() {
4969 return map()->constructor();
4970}
4971
4972
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004973bool JSReceiver::HasProperty(String* name) {
4974 if (IsJSProxy()) {
4975 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4976 }
4977 return GetPropertyAttribute(name) != ABSENT;
4978}
4979
4980
4981bool JSReceiver::HasLocalProperty(String* name) {
4982 if (IsJSProxy()) {
4983 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4984 }
4985 return GetLocalPropertyAttribute(name) != ABSENT;
4986}
4987
4988
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004989PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004990 return GetPropertyAttributeWithReceiver(this, key);
4991}
4992
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004993// TODO(504): this may be useful in other places too where JSGlobalProxy
4994// is used.
4995Object* JSObject::BypassGlobalProxy() {
4996 if (IsJSGlobalProxy()) {
4997 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004998 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004999 ASSERT(proto->IsJSGlobalObject());
5000 return proto;
5001 }
5002 return this;
5003}
5004
5005
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005006MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
5007 return IsJSProxy()
5008 ? JSProxy::cast(this)->GetIdentityHash(flag)
5009 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005010}
5011
5012
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005013bool JSReceiver::HasElement(uint32_t index) {
5014 if (IsJSProxy()) {
5015 return JSProxy::cast(this)->HasElementWithHandler(index);
5016 }
5017 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005018}
5019
5020
5021bool AccessorInfo::all_can_read() {
5022 return BooleanBit::get(flag(), kAllCanReadBit);
5023}
5024
5025
5026void AccessorInfo::set_all_can_read(bool value) {
5027 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
5028}
5029
5030
5031bool AccessorInfo::all_can_write() {
5032 return BooleanBit::get(flag(), kAllCanWriteBit);
5033}
5034
5035
5036void AccessorInfo::set_all_can_write(bool value) {
5037 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
5038}
5039
5040
ager@chromium.org870a0b62008-11-04 11:43:05 +00005041bool AccessorInfo::prohibits_overwriting() {
5042 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
5043}
5044
5045
5046void AccessorInfo::set_prohibits_overwriting(bool value) {
5047 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
5048}
5049
5050
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005051PropertyAttributes AccessorInfo::property_attributes() {
5052 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
5053}
5054
5055
5056void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00005057 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005058}
5059
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005060
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005061bool AccessorInfo::IsCompatibleReceiver(Object* receiver) {
5062 Object* function_template = expected_receiver_type();
5063 if (!function_template->IsFunctionTemplateInfo()) return true;
5064 return receiver->IsInstanceOf(FunctionTemplateInfo::cast(function_template));
5065}
5066
5067
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005068template<typename Shape, typename Key>
5069void Dictionary<Shape, Key>::SetEntry(int entry,
5070 Object* key,
5071 Object* value) {
5072 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
5073}
5074
5075
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005076template<typename Shape, typename Key>
5077void Dictionary<Shape, Key>::SetEntry(int entry,
5078 Object* key,
5079 Object* value,
5080 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00005081 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005082 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005083 AssertNoAllocation no_gc;
5084 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005085 FixedArray::set(index, key, mode);
5086 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005087 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005088}
5089
5090
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005091bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
5092 ASSERT(other->IsNumber());
5093 return key == static_cast<uint32_t>(other->Number());
5094}
5095
5096
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005097uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
5098 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005099}
5100
5101
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005102uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
5103 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005104 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005105 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005106}
5107
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005108uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
5109 return ComputeIntegerHash(key, seed);
5110}
5111
5112uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
5113 uint32_t seed,
5114 Object* other) {
5115 ASSERT(other->IsNumber());
5116 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
5117}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005118
5119MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
5120 return Isolate::Current()->heap()->NumberFromUint32(key);
5121}
5122
5123
5124bool StringDictionaryShape::IsMatch(String* key, Object* other) {
5125 // We know that all entries in a hash table had their hash keys created.
5126 // Use that knowledge to have fast failure.
5127 if (key->Hash() != String::cast(other)->Hash()) return false;
5128 return key->Equals(String::cast(other));
5129}
5130
5131
5132uint32_t StringDictionaryShape::Hash(String* key) {
5133 return key->Hash();
5134}
5135
5136
5137uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
5138 return String::cast(other)->Hash();
5139}
5140
5141
5142MaybeObject* StringDictionaryShape::AsObject(String* key) {
5143 return key;
5144}
5145
5146
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005147template <int entrysize>
5148bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
5149 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005150}
5151
5152
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005153template <int entrysize>
5154uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005155 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
5156 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005157}
5158
5159
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005160template <int entrysize>
5161uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
5162 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005163 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
5164 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005165}
5166
5167
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005168template <int entrysize>
5169MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005170 return key;
5171}
5172
5173
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005174void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005175 // No write barrier is needed since empty_fixed_array is not in new space.
5176 // Please note this function is used during marking:
5177 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00005178 // - IncrementalMarking::Step
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005179 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
5180 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005181}
5182
5183
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005184void JSArray::EnsureSize(int required_size) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005185 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005186 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005187 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
5188 if (elts->length() < required_size) {
5189 // Doubling in size would be overkill, but leave some slack to avoid
5190 // constantly growing.
5191 Expand(required_size + (required_size >> 3));
5192 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005193 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005194 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
5195 // Expand will allocate a new backing store in new space even if the size
5196 // we asked for isn't larger than what we had before.
5197 Expand(required_size);
5198 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005199}
5200
5201
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005202void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005203 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005204 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
5205}
5206
5207
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005208bool JSArray::AllowsSetElementsLength() {
5209 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
5210 ASSERT(result == !HasExternalArrayElements());
5211 return result;
5212}
5213
5214
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005215MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
5216 MaybeObject* maybe_result = EnsureCanContainElements(
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005217 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005218 if (maybe_result->IsFailure()) return maybe_result;
5219 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005220 IsFastDoubleElementsKind(GetElementsKind())) ||
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005221 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005222 (IsFastObjectElementsKind(GetElementsKind()) ||
5223 (IsFastSmiElementsKind(GetElementsKind()) &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005224 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00005225 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005226 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005227 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005228}
5229
5230
lrn@chromium.org303ada72010-10-27 09:33:13 +00005231MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005232 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005233 return GetHeap()->CopyFixedArray(this);
5234}
5235
5236
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005237MaybeObject* FixedDoubleArray::Copy() {
5238 if (length() == 0) return this;
5239 return GetHeap()->CopyFixedDoubleArray(this);
5240}
5241
5242
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005243void TypeFeedbackCells::SetAstId(int index, Smi* id) {
5244 set(1 + index * 2, id);
5245}
5246
5247
5248Smi* TypeFeedbackCells::AstId(int index) {
5249 return Smi::cast(get(1 + index * 2));
5250}
5251
5252
5253void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
5254 set(index * 2, cell);
5255}
5256
5257
5258JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
5259 return JSGlobalPropertyCell::cast(get(index * 2));
5260}
5261
5262
5263Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
5264 return isolate->factory()->the_hole_value();
5265}
5266
5267
5268Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
5269 return isolate->factory()->undefined_value();
5270}
5271
5272
5273Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
5274 return heap->raw_unchecked_the_hole_value();
5275}
5276
5277
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005278SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00005279SMI_ACCESSORS(TypeFeedbackInfo, ic_with_type_info_count,
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005280 kIcWithTypeinfoCountOffset)
5281ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
5282 kTypeFeedbackCellsOffset)
5283
5284
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00005285SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
5286
5287
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005288Relocatable::Relocatable(Isolate* isolate) {
5289 ASSERT(isolate == Isolate::Current());
5290 isolate_ = isolate;
5291 prev_ = isolate->relocatable_top();
5292 isolate->set_relocatable_top(this);
5293}
5294
5295
5296Relocatable::~Relocatable() {
5297 ASSERT(isolate_ == Isolate::Current());
5298 ASSERT_EQ(isolate_->relocatable_top(), this);
5299 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005300}
5301
5302
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005303int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
5304 return map->instance_size();
5305}
5306
5307
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005308void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005309 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005310 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005311}
5312
5313
5314template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005315void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005316 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005317 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005318}
5319
5320
5321void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
5322 typedef v8::String::ExternalAsciiStringResource Resource;
5323 v->VisitExternalAsciiString(
5324 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5325}
5326
5327
5328template<typename StaticVisitor>
5329void ExternalAsciiString::ExternalAsciiStringIterateBody() {
5330 typedef v8::String::ExternalAsciiStringResource Resource;
5331 StaticVisitor::VisitExternalAsciiString(
5332 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5333}
5334
5335
5336void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
5337 typedef v8::String::ExternalStringResource Resource;
5338 v->VisitExternalTwoByteString(
5339 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5340}
5341
5342
5343template<typename StaticVisitor>
5344void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
5345 typedef v8::String::ExternalStringResource Resource;
5346 StaticVisitor::VisitExternalTwoByteString(
5347 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5348}
5349
5350#define SLOT_ADDR(obj, offset) \
5351 reinterpret_cast<Object**>((obj)->address() + offset)
5352
5353template<int start_offset, int end_offset, int size>
5354void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
5355 HeapObject* obj,
5356 ObjectVisitor* v) {
5357 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
5358}
5359
5360
5361template<int start_offset>
5362void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
5363 int object_size,
5364 ObjectVisitor* v) {
5365 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
5366}
5367
5368#undef SLOT_ADDR
5369
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005370#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005371#undef CAST_ACCESSOR
5372#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005373#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005374#undef ACCESSORS_TO_SMI
5375#undef SMI_ACCESSORS
5376#undef BOOL_GETTER
5377#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005378#undef FIELD_ADDR
5379#undef READ_FIELD
5380#undef WRITE_FIELD
5381#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005382#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005383#undef READ_DOUBLE_FIELD
5384#undef WRITE_DOUBLE_FIELD
5385#undef READ_INT_FIELD
5386#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005387#undef READ_INTPTR_FIELD
5388#undef WRITE_INTPTR_FIELD
5389#undef READ_UINT32_FIELD
5390#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005391#undef READ_SHORT_FIELD
5392#undef WRITE_SHORT_FIELD
5393#undef READ_BYTE_FIELD
5394#undef WRITE_BYTE_FIELD
5395
5396
5397} } // namespace v8::internal
5398
5399#endif // V8_OBJECTS_INL_H_