blob: f4e0767198049a7cad3a63877ca376da7d42b973 [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
3526 ASSERT(len == 0 ||
3527 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.org753aee42012-07-17 16:15:42 +00003585MaybeObject* Map::AddTransition(String* key, Map* target) {
3586 if (HasTransitionArray()) return transitions()->CopyInsert(key, target);
3587 return TransitionArray::NewWith(key, target);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003588}
3589
verwaest@chromium.org753aee42012-07-17 16:15:42 +00003590
3591void Map::SetTransition(int transition_index, Map* target) {
3592 transitions()->SetTarget(transition_index, target);
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00003593}
3594
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003595
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003596// If the map is using the empty descriptor array, install a new empty
3597// descriptor array that will contain an elements transition.
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003598static MaybeObject* AllowTransitions(Map* map) {
3599 if (map->instance_descriptors()->MayContainTransitions()) return map;
3600 DescriptorArray* descriptors;
3601 MaybeObject* maybe_descriptors =
3602 DescriptorArray::Allocate(0, DescriptorArray::CANNOT_BE_SHARED);
3603 if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors;
3604 map->set_instance_descriptors(descriptors);
3605 return descriptors;
3606}
3607
3608
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003609// If the descriptor is using the empty transition array, install a new empty
3610// transition array that will have place for an element transition.
3611static MaybeObject* EnsureHasTransitionArray(Map* map) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003612 if (map->HasTransitionArray()) return map;
3613
3614 AllowTransitions(map);
3615
3616 TransitionArray* transitions;
3617 MaybeObject* maybe_transitions = TransitionArray::Allocate(0);
3618 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
3619 MaybeObject* added_transitions = map->set_transitions(transitions);
3620 if (added_transitions->IsFailure()) return added_transitions;
3621 return transitions;
3622}
3623
3624
3625MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003626 MaybeObject* allow_elements = EnsureHasTransitionArray(this);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003627 if (allow_elements->IsFailure()) return allow_elements;
3628 transitions()->set_elements_transition(transitioned_map);
3629 return this;
3630}
3631
3632
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003633FixedArray* Map::GetPrototypeTransitions() {
3634 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
3635 if (!transitions()->HasPrototypeTransitions()) {
3636 return GetHeap()->empty_fixed_array();
3637 }
3638 return transitions()->GetPrototypeTransitions();
3639}
3640
3641
3642MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
3643 MaybeObject* allow_prototype = EnsureHasTransitionArray(this);
3644 if (allow_prototype->IsFailure()) return allow_prototype;
3645#ifdef DEBUG
3646 if (HasPrototypeTransitions()) {
3647 ASSERT(GetPrototypeTransitions() != proto_transitions);
3648 ZapPrototypeTransitions();
3649 }
3650#endif
3651 transitions()->SetPrototypeTransitions(proto_transitions);
3652 return this;
3653}
3654
3655
3656bool Map::HasPrototypeTransitions() {
3657 return HasTransitionArray() && transitions()->HasPrototypeTransitions();
3658}
3659
3660
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003661TransitionArray* Map::transitions() {
3662 return instance_descriptors()->transitions();
3663}
3664
3665
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003666void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003667#ifdef DEBUG
3668 ZapTransitions();
3669#endif
3670 DescriptorArray* descriptors = instance_descriptors();
3671 if (descriptors->number_of_descriptors() == 0) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003672 ClearDescriptorArray(heap, mode);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00003673 } else {
3674 descriptors->ClearTransitions();
3675 }
3676}
3677
3678
3679MaybeObject* Map::set_transitions(TransitionArray* transitions_array) {
3680 MaybeObject* allow_transitions = AllowTransitions(this);
3681 if (allow_transitions->IsFailure()) return allow_transitions;
3682#ifdef DEBUG
3683 if (HasTransitionArray()) {
3684 ASSERT(transitions() != transitions_array);
3685 ZapTransitions();
3686 }
3687#endif
3688 instance_descriptors()->set_transitions(transitions_array);
3689 return this;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003690}
3691
3692
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003693void Map::init_back_pointer(Object* undefined) {
3694 ASSERT(undefined->IsUndefined());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003695 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, undefined);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003696}
3697
3698
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003699void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003700 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
3701 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
3702 (value->IsMap() && GetBackPointer()->IsUndefined()));
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003703 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset);
verwaest@chromium.org753aee42012-07-17 16:15:42 +00003704 if (object->IsDescriptorArray()) {
3705 DescriptorArray::cast(object)->set_back_pointer_storage(value);
3706 } else {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003707 WRITE_FIELD(this, kInstanceDescriptorsOrBackPointerOffset, value);
3708 CONDITIONAL_WRITE_BARRIER(
3709 GetHeap(), this, kInstanceDescriptorsOrBackPointerOffset, value, mode);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003710 }
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003711}
3712
3713
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003714// Can either be Smi (no transitions), normal transition array, or a transition
3715// array with the header overwritten as a Smi (thus iterating).
3716TransitionArray* Map::unchecked_transition_array() {
3717 ASSERT(HasTransitionArray());
3718 Object* object = *HeapObject::RawField(instance_descriptors(),
3719 DescriptorArray::kTransitionsOffset);
3720 ASSERT(!object->IsSmi());
3721 TransitionArray* transition_array = static_cast<TransitionArray*>(object);
3722 return transition_array;
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003723}
3724
3725
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003726HeapObject* Map::UncheckedPrototypeTransitions() {
3727 ASSERT(HasTransitionArray());
3728 ASSERT(unchecked_transition_array()->HasPrototypeTransitions());
3729 return unchecked_transition_array()->UncheckedPrototypeTransitions();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003730}
3731
3732
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003733ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003734ACCESSORS(Map, constructor, Object, kConstructorOffset)
3735
3736ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003737ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003738ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003739
3740ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3741ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003742ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003743
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003744ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003745
3746ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3747ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3748ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3749ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003750ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003751ACCESSORS(AccessorInfo, expected_receiver_type, Object,
3752 kExpectedReceiverTypeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003753
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003754ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3755ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3756
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003757ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3758ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3759ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3760
3761ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3762ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3763ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3764ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3765ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3766ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3767
3768ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3769ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3770
3771ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3772ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3773
3774ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3775ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003776ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3777 kPropertyAccessorsOffset)
3778ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3779 kPrototypeTemplateOffset)
3780ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3781ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3782 kNamedPropertyHandlerOffset)
3783ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3784 kIndexedPropertyHandlerOffset)
3785ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3786 kInstanceTemplateOffset)
3787ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3788ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003789ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3790 kInstanceCallHandlerOffset)
3791ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3792 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003793ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003794
3795ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003796ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3797 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003798
3799ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3800ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3801
3802ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3803
3804ACCESSORS(Script, source, Object, kSourceOffset)
3805ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003806ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003807ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
3808ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003809ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003810ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003811ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003812ACCESSORS_TO_SMI(Script, type, kTypeOffset)
3813ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
3814ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003815ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003816ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003817ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
3818 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003819
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003820#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003821ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3822ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3823ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3824ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3825
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003826ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
3827ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
3828ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003829ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003830#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003831
3832ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003833ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
3834 kOptimizedCodeMapOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003835ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3836ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003837ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3838 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003839ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003840ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3841ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003842ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003843ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3844 kThisPropertyAssignmentsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003845SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003846
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00003847
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003848BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3849 kHiddenPrototypeBit)
3850BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3851BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3852 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003853BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3854 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003855BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3856 kIsExpressionBit)
3857BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3858 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003859BOOL_GETTER(SharedFunctionInfo,
3860 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003861 has_only_simple_this_property_assignments,
3862 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003863BOOL_ACCESSORS(SharedFunctionInfo,
3864 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003865 allows_lazy_compilation,
3866 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003867BOOL_ACCESSORS(SharedFunctionInfo,
3868 compiler_hints,
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003869 allows_lazy_compilation_without_context,
3870 kAllowLazyCompilationWithoutContext)
3871BOOL_ACCESSORS(SharedFunctionInfo,
3872 compiler_hints,
whesse@chromium.org7b260152011-06-20 15:33:18 +00003873 uses_arguments,
3874 kUsesArguments)
3875BOOL_ACCESSORS(SharedFunctionInfo,
3876 compiler_hints,
3877 has_duplicate_parameters,
3878 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003879
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003880
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003881#if V8_HOST_ARCH_32_BIT
3882SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3883SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003884 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003885SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003886 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003887SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3888SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003889 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003890SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3891SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003892 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003893SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003894 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003895SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003896 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003897SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003898SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
3899SMI_ACCESSORS(SharedFunctionInfo,
3900 stress_deopt_counter,
3901 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003902#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003903
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003904#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003905 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003906 int holder::name() { \
3907 int value = READ_INT_FIELD(this, offset); \
3908 ASSERT(kHeapObjectTag == 1); \
3909 ASSERT((value & kHeapObjectTag) == 0); \
3910 return value >> 1; \
3911 } \
3912 void holder::set_##name(int value) { \
3913 ASSERT(kHeapObjectTag == 1); \
3914 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3915 (value & 0xC0000000) == 0x000000000); \
3916 WRITE_INT_FIELD(this, \
3917 offset, \
3918 (value << 1) & ~kHeapObjectTag); \
3919 }
3920
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003921#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3922 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003923 INT_ACCESSORS(holder, name, offset)
3924
3925
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003926PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003927PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3928 formal_parameter_count,
3929 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003930
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003931PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3932 expected_nof_properties,
3933 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003934PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3935
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003936PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3937PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3938 start_position_and_type,
3939 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003940
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003941PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3942 function_token_position,
3943 kFunctionTokenPositionOffset)
3944PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3945 compiler_hints,
3946 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003947
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003948PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3949 this_property_assignments_count,
3950 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003951PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003952
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003953PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, counters, kCountersOffset)
3954PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3955 stress_deopt_counter,
3956 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003957#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003958
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003959
3960int SharedFunctionInfo::construction_count() {
3961 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3962}
3963
3964
3965void SharedFunctionInfo::set_construction_count(int value) {
3966 ASSERT(0 <= value && value < 256);
3967 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3968}
3969
3970
whesse@chromium.org7b260152011-06-20 15:33:18 +00003971BOOL_ACCESSORS(SharedFunctionInfo,
3972 compiler_hints,
3973 live_objects_may_exist,
3974 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003975
3976
3977bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003978 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003979}
3980
3981
whesse@chromium.org7b260152011-06-20 15:33:18 +00003982BOOL_GETTER(SharedFunctionInfo,
3983 compiler_hints,
3984 optimization_disabled,
3985 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003986
3987
3988void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3989 set_compiler_hints(BooleanBit::set(compiler_hints(),
3990 kOptimizationDisabled,
3991 disable));
3992 // If disabling optimizations we reflect that in the code object so
3993 // it will not be counted as optimizable code.
3994 if ((code()->kind() == Code::FUNCTION) && disable) {
3995 code()->set_optimizable(false);
3996 }
3997}
3998
3999
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004000int SharedFunctionInfo::profiler_ticks() {
4001 if (code()->kind() != Code::FUNCTION) return 0;
4002 return code()->profiler_ticks();
4003}
4004
4005
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004006LanguageMode SharedFunctionInfo::language_mode() {
4007 int hints = compiler_hints();
4008 if (BooleanBit::get(hints, kExtendedModeFunction)) {
4009 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
4010 return EXTENDED_MODE;
4011 }
4012 return BooleanBit::get(hints, kStrictModeFunction)
4013 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004014}
4015
4016
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004017void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
4018 // We only allow language mode transitions that go set the same language mode
4019 // again or go up in the chain:
4020 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
4021 ASSERT(this->language_mode() == CLASSIC_MODE ||
4022 this->language_mode() == language_mode ||
4023 language_mode == EXTENDED_MODE);
4024 int hints = compiler_hints();
4025 hints = BooleanBit::set(
4026 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
4027 hints = BooleanBit::set(
4028 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
4029 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004030}
4031
4032
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004033bool SharedFunctionInfo::is_classic_mode() {
4034 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
4035}
4036
4037BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
4038 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004039BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
4040BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
4041 name_should_print_as_anonymous,
4042 kNameShouldPrintAsAnonymous)
4043BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
4044BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00004045BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
4046BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
4047 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00004048BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004049BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_cache, kDontCache)
whesse@chromium.org7b260152011-06-20 15:33:18 +00004050
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004051void SharedFunctionInfo::BeforeVisitingPointers() {
4052 if (IsInobjectSlackTrackingInProgress()) DetachInitialMap();
4053
4054 // Flush optimized code map on major GC.
4055 // Note: we may experiment with rebuilding it or retaining entries
4056 // which should survive as we iterate through optimized functions
4057 // anyway.
4058 set_optimized_code_map(Smi::FromInt(0));
4059}
4060
4061
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004062ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
4063ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
4064
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00004065ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
4066
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00004067bool Script::HasValidSource() {
4068 Object* src = this->source();
4069 if (!src->IsString()) return true;
4070 String* src_str = String::cast(src);
4071 if (!StringShape(src_str).IsExternal()) return true;
4072 if (src_str->IsAsciiRepresentation()) {
4073 return ExternalAsciiString::cast(src)->resource() != NULL;
4074 } else if (src_str->IsTwoByteRepresentation()) {
4075 return ExternalTwoByteString::cast(src)->resource() != NULL;
4076 }
4077 return true;
4078}
4079
4080
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00004081void SharedFunctionInfo::DontAdaptArguments() {
4082 ASSERT(code()->kind() == Code::BUILTIN);
4083 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
4084}
4085
4086
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004087int SharedFunctionInfo::start_position() {
4088 return start_position_and_type() >> kStartPositionShift;
4089}
4090
4091
4092void SharedFunctionInfo::set_start_position(int start_position) {
4093 set_start_position_and_type((start_position << kStartPositionShift)
4094 | (start_position_and_type() & ~kStartPositionMask));
4095}
4096
4097
4098Code* SharedFunctionInfo::code() {
4099 return Code::cast(READ_FIELD(this, kCodeOffset));
4100}
4101
4102
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004103Code* SharedFunctionInfo::unchecked_code() {
4104 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
4105}
4106
4107
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004108void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004109 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004110 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004111}
4112
4113
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004114ScopeInfo* SharedFunctionInfo::scope_info() {
4115 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00004116}
4117
4118
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004119void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00004120 WriteBarrierMode mode) {
4121 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004122 CONDITIONAL_WRITE_BARRIER(GetHeap(),
4123 this,
4124 kScopeInfoOffset,
4125 reinterpret_cast<Object*>(value),
4126 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00004127}
4128
4129
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004130bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004131 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004132 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004133}
4134
4135
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004136bool SharedFunctionInfo::IsApiFunction() {
4137 return function_data()->IsFunctionTemplateInfo();
4138}
4139
4140
4141FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
4142 ASSERT(IsApiFunction());
4143 return FunctionTemplateInfo::cast(function_data());
4144}
4145
4146
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004147bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00004148 return function_data()->IsSmi();
4149}
4150
4151
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004152BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
4153 ASSERT(HasBuiltinFunctionId());
4154 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004155}
4156
4157
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004158int SharedFunctionInfo::code_age() {
4159 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
4160}
4161
4162
4163void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00004164 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
4165 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004166}
4167
4168
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004169int SharedFunctionInfo::ic_age() {
4170 return ICAgeBits::decode(counters());
4171}
4172
4173
4174void SharedFunctionInfo::set_ic_age(int ic_age) {
4175 set_counters(ICAgeBits::update(counters(), ic_age));
4176}
4177
4178
4179int SharedFunctionInfo::deopt_count() {
4180 return DeoptCountBits::decode(counters());
4181}
4182
4183
4184void SharedFunctionInfo::set_deopt_count(int deopt_count) {
4185 set_counters(DeoptCountBits::update(counters(), deopt_count));
4186}
4187
4188
4189void SharedFunctionInfo::increment_deopt_count() {
4190 int value = counters();
4191 int deopt_count = DeoptCountBits::decode(value);
4192 deopt_count = (deopt_count + 1) & DeoptCountBits::kMax;
4193 set_counters(DeoptCountBits::update(value, deopt_count));
4194}
4195
4196
4197int SharedFunctionInfo::opt_reenable_tries() {
4198 return OptReenableTriesBits::decode(counters());
4199}
4200
4201
4202void SharedFunctionInfo::set_opt_reenable_tries(int tries) {
4203 set_counters(OptReenableTriesBits::update(counters(), tries));
4204}
4205
4206
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004207bool SharedFunctionInfo::has_deoptimization_support() {
4208 Code* code = this->code();
4209 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
4210}
4211
4212
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004213void SharedFunctionInfo::TryReenableOptimization() {
4214 int tries = opt_reenable_tries();
4215 set_opt_reenable_tries((tries + 1) & OptReenableTriesBits::kMax);
4216 // We reenable optimization whenever the number of tries is a large
4217 // enough power of 2.
4218 if (tries >= 16 && (((tries - 1) & tries) == 0)) {
4219 set_optimization_disabled(false);
4220 set_opt_count(0);
4221 set_deopt_count(0);
4222 code()->set_optimizable(true);
4223 }
4224}
4225
4226
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004227bool JSFunction::IsBuiltin() {
4228 return context()->global()->IsJSBuiltinsObject();
4229}
4230
4231
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004232bool JSFunction::NeedsArgumentsAdaption() {
4233 return shared()->formal_parameter_count() !=
4234 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
4235}
4236
4237
4238bool JSFunction::IsOptimized() {
4239 return code()->kind() == Code::OPTIMIZED_FUNCTION;
4240}
4241
4242
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00004243bool JSFunction::IsOptimizable() {
4244 return code()->kind() == Code::FUNCTION && code()->optimizable();
4245}
4246
4247
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004248bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004249 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004250}
4251
4252
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004253bool JSFunction::IsMarkedForParallelRecompilation() {
4254 return code() ==
4255 GetIsolate()->builtins()->builtin(Builtins::kParallelRecompile);
4256}
4257
4258
4259bool JSFunction::IsInRecompileQueue() {
4260 return code() == GetIsolate()->builtins()->builtin(
4261 Builtins::kInRecompileQueue);
4262}
4263
4264
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004265Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004266 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004267}
4268
4269
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004270Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004271 return reinterpret_cast<Code*>(
4272 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004273}
4274
4275
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004276void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004277 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004278 Address entry = value->entry();
4279 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004280 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
4281 this,
4282 HeapObject::RawField(this, kCodeEntryOffset),
4283 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004284}
4285
4286
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004287void JSFunction::ReplaceCode(Code* code) {
4288 bool was_optimized = IsOptimized();
4289 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
4290
4291 set_code(code);
4292
4293 // Add/remove the function from the list of optimized functions for this
4294 // context based on the state change.
4295 if (!was_optimized && is_optimized) {
4296 context()->global_context()->AddOptimizedFunction(this);
4297 }
4298 if (was_optimized && !is_optimized) {
4299 context()->global_context()->RemoveOptimizedFunction(this);
4300 }
4301}
4302
4303
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004304Context* JSFunction::context() {
4305 return Context::cast(READ_FIELD(this, kContextOffset));
4306}
4307
4308
4309Object* JSFunction::unchecked_context() {
4310 return READ_FIELD(this, kContextOffset);
4311}
4312
4313
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004314SharedFunctionInfo* JSFunction::unchecked_shared() {
4315 return reinterpret_cast<SharedFunctionInfo*>(
4316 READ_FIELD(this, kSharedFunctionInfoOffset));
4317}
4318
4319
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004320void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004321 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004322 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004323 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004324}
4325
4326ACCESSORS(JSFunction, prototype_or_initial_map, Object,
4327 kPrototypeOrInitialMapOffset)
4328
4329
4330Map* JSFunction::initial_map() {
4331 return Map::cast(prototype_or_initial_map());
4332}
4333
4334
4335void JSFunction::set_initial_map(Map* value) {
4336 set_prototype_or_initial_map(value);
4337}
4338
4339
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004340MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
4341 Map* initial_map) {
4342 Context* global_context = context()->global_context();
4343 Object* array_function =
4344 global_context->get(Context::ARRAY_FUNCTION_INDEX);
4345 if (array_function->IsJSFunction() &&
4346 this == JSFunction::cast(array_function)) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004347 // Replace all of the cached initial array maps in the global context with
4348 // the appropriate transitioned elements kind maps.
4349 Heap* heap = GetHeap();
4350 MaybeObject* maybe_maps =
4351 heap->AllocateFixedArrayWithHoles(kElementsKindCount);
4352 FixedArray* maps;
4353 if (!maybe_maps->To(&maps)) return maybe_maps;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004354
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004355 Map* current_map = initial_map;
4356 ElementsKind kind = current_map->elements_kind();
4357 ASSERT(kind == GetInitialFastElementsKind());
4358 maps->set(kind, current_map);
4359 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
4360 i < kFastElementsKindCount; ++i) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004361 Map* new_map;
4362 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
4363 MaybeObject* maybe_new_map =
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004364 current_map->CopyAsElementsKind(next_kind, INSERT_TRANSITION);
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004365 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
4366 maps->set(next_kind, new_map);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004367 current_map = new_map;
4368 }
4369 global_context->set_js_array_maps(maps);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004370 }
4371 set_initial_map(initial_map);
4372 return this;
4373}
4374
4375
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004376bool JSFunction::has_initial_map() {
4377 return prototype_or_initial_map()->IsMap();
4378}
4379
4380
4381bool JSFunction::has_instance_prototype() {
4382 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4383}
4384
4385
4386bool JSFunction::has_prototype() {
4387 return map()->has_non_instance_prototype() || has_instance_prototype();
4388}
4389
4390
4391Object* JSFunction::instance_prototype() {
4392 ASSERT(has_instance_prototype());
4393 if (has_initial_map()) return initial_map()->prototype();
4394 // When there is no initial map and the prototype is a JSObject, the
4395 // initial map field is used for the prototype field.
4396 return prototype_or_initial_map();
4397}
4398
4399
4400Object* JSFunction::prototype() {
4401 ASSERT(has_prototype());
4402 // If the function's prototype property has been set to a non-JSObject
4403 // value, that value is stored in the constructor field of the map.
4404 if (map()->has_non_instance_prototype()) return map()->constructor();
4405 return instance_prototype();
4406}
4407
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004408
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00004409bool JSFunction::should_have_prototype() {
4410 return map()->function_with_prototype();
4411}
4412
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004413
4414bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004415 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004416}
4417
4418
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004419FixedArray* JSFunction::literals() {
4420 ASSERT(!shared()->bound());
4421 return literals_or_bindings();
4422}
4423
4424
4425void JSFunction::set_literals(FixedArray* literals) {
4426 ASSERT(!shared()->bound());
4427 set_literals_or_bindings(literals);
4428}
4429
4430
4431FixedArray* JSFunction::function_bindings() {
4432 ASSERT(shared()->bound());
4433 return literals_or_bindings();
4434}
4435
4436
4437void JSFunction::set_function_bindings(FixedArray* bindings) {
4438 ASSERT(shared()->bound());
4439 // Bound function literal may be initialized to the empty fixed array
4440 // before the bindings are set.
4441 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4442 bindings->map() == GetHeap()->fixed_cow_array_map());
4443 set_literals_or_bindings(bindings);
4444}
4445
4446
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004447int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004448 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004449 return literals()->length();
4450}
4451
4452
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004453Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004454 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004455 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004456}
4457
4458
4459void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4460 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004461 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004462 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004463 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004464}
4465
4466
4467Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004468 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004469 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4470}
4471
4472
4473void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4474 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004475 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004476 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004477 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004478}
4479
4480
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004481ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004482ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004483ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4484ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4485
4486
4487void JSProxy::InitializeBody(int object_size, Object* value) {
4488 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4489 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4490 WRITE_FIELD(this, offset, value);
4491 }
4492}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004493
4494
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004495ACCESSORS(JSSet, table, Object, kTableOffset)
4496ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004497ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4498ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004499
4500
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004501Address Foreign::foreign_address() {
4502 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004503}
4504
4505
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004506void Foreign::set_foreign_address(Address value) {
4507 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004508}
4509
4510
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004511ACCESSORS(JSModule, context, Object, kContextOffset)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004512ACCESSORS(JSModule, scope_info, ScopeInfo, kScopeInfoOffset)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004513
4514
4515JSModule* JSModule::cast(Object* obj) {
4516 ASSERT(obj->IsJSModule());
4517 ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
4518 return reinterpret_cast<JSModule*>(obj);
4519}
4520
4521
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004522ACCESSORS(JSValue, value, Object, kValueOffset)
4523
4524
4525JSValue* JSValue::cast(Object* obj) {
4526 ASSERT(obj->IsJSValue());
4527 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4528 return reinterpret_cast<JSValue*>(obj);
4529}
4530
4531
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004532ACCESSORS(JSDate, value, Object, kValueOffset)
4533ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4534ACCESSORS(JSDate, year, Object, kYearOffset)
4535ACCESSORS(JSDate, month, Object, kMonthOffset)
4536ACCESSORS(JSDate, day, Object, kDayOffset)
4537ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4538ACCESSORS(JSDate, hour, Object, kHourOffset)
4539ACCESSORS(JSDate, min, Object, kMinOffset)
4540ACCESSORS(JSDate, sec, Object, kSecOffset)
4541
4542
4543JSDate* JSDate::cast(Object* obj) {
4544 ASSERT(obj->IsJSDate());
4545 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4546 return reinterpret_cast<JSDate*>(obj);
4547}
4548
4549
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004550ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4551ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4552ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4553ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4554ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4555SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4556SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4557
4558
4559JSMessageObject* JSMessageObject::cast(Object* obj) {
4560 ASSERT(obj->IsJSMessageObject());
4561 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4562 return reinterpret_cast<JSMessageObject*>(obj);
4563}
4564
4565
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004566INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004567ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004568ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004569ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004570ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004571ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00004572INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004573
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004574byte* Code::instruction_start() {
4575 return FIELD_ADDR(this, kHeaderSize);
4576}
4577
4578
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004579byte* Code::instruction_end() {
4580 return instruction_start() + instruction_size();
4581}
4582
4583
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004584int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004585 return RoundUp(instruction_size(), kObjectAlignment);
4586}
4587
4588
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004589FixedArray* Code::unchecked_deoptimization_data() {
4590 return reinterpret_cast<FixedArray*>(
4591 READ_FIELD(this, kDeoptimizationDataOffset));
4592}
4593
4594
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004595ByteArray* Code::unchecked_relocation_info() {
4596 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004597}
4598
4599
4600byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004601 return unchecked_relocation_info()->GetDataStartAddress();
4602}
4603
4604
4605int Code::relocation_size() {
4606 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004607}
4608
4609
4610byte* Code::entry() {
4611 return instruction_start();
4612}
4613
4614
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004615bool Code::contains(byte* inner_pointer) {
4616 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004617}
4618
4619
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004620ACCESSORS(JSArray, length, Object, kLengthOffset)
4621
4622
ager@chromium.org236ad962008-09-25 09:45:57 +00004623ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004624
4625
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004626JSRegExp::Type JSRegExp::TypeTag() {
4627 Object* data = this->data();
4628 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4629 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4630 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004631}
4632
4633
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004634JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4635 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4636 return static_cast<JSRegExp::Type>(smi->value());
4637}
4638
4639
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004640int JSRegExp::CaptureCount() {
4641 switch (TypeTag()) {
4642 case ATOM:
4643 return 0;
4644 case IRREGEXP:
4645 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4646 default:
4647 UNREACHABLE();
4648 return -1;
4649 }
4650}
4651
4652
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004653JSRegExp::Flags JSRegExp::GetFlags() {
4654 ASSERT(this->data()->IsFixedArray());
4655 Object* data = this->data();
4656 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4657 return Flags(smi->value());
4658}
4659
4660
4661String* JSRegExp::Pattern() {
4662 ASSERT(this->data()->IsFixedArray());
4663 Object* data = this->data();
4664 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4665 return pattern;
4666}
4667
4668
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004669Object* JSRegExp::DataAt(int index) {
4670 ASSERT(TypeTag() != NOT_COMPILED);
4671 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004672}
4673
4674
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004675Object* JSRegExp::DataAtUnchecked(int index) {
4676 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4677 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4678 return READ_FIELD(fa, offset);
4679}
4680
4681
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004682void JSRegExp::SetDataAt(int index, Object* value) {
4683 ASSERT(TypeTag() != NOT_COMPILED);
4684 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4685 FixedArray::cast(data())->set(index, value);
4686}
4687
4688
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004689void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4690 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4691 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4692 if (value->IsSmi()) {
4693 fa->set_unchecked(index, Smi::cast(value));
4694 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004695 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004696 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4697 }
4698}
4699
4700
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004701ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004702 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004703#if DEBUG
4704 FixedArrayBase* fixed_array =
4705 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4706 Map* map = fixed_array->map();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004707 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
4708 (map == GetHeap()->fixed_array_map() ||
4709 map == GetHeap()->fixed_cow_array_map())) ||
4710 (IsFastDoubleElementsKind(kind) &&
4711 (fixed_array->IsFixedDoubleArray() ||
4712 fixed_array == GetHeap()->empty_fixed_array())) ||
4713 (kind == DICTIONARY_ELEMENTS &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004714 fixed_array->IsFixedArray() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004715 fixed_array->IsDictionary()) ||
4716 (kind > DICTIONARY_ELEMENTS));
4717 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4718 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004719#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004720 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004721}
4722
4723
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004724ElementsAccessor* JSObject::GetElementsAccessor() {
4725 return ElementsAccessor::ForKind(GetElementsKind());
4726}
4727
4728
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004729bool JSObject::HasFastObjectElements() {
4730 return IsFastObjectElementsKind(GetElementsKind());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004731}
4732
4733
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004734bool JSObject::HasFastSmiElements() {
4735 return IsFastSmiElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004736}
4737
4738
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004739bool JSObject::HasFastSmiOrObjectElements() {
4740 return IsFastSmiOrObjectElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004741}
4742
4743
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004744bool JSObject::HasFastDoubleElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004745 return IsFastDoubleElementsKind(GetElementsKind());
4746}
4747
4748
4749bool JSObject::HasFastHoleyElements() {
4750 return IsFastHoleyElementsKind(GetElementsKind());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004751}
4752
4753
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004754bool JSObject::HasDictionaryElements() {
4755 return GetElementsKind() == DICTIONARY_ELEMENTS;
4756}
4757
4758
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004759bool JSObject::HasNonStrictArgumentsElements() {
4760 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4761}
4762
4763
ager@chromium.org3811b432009-10-28 14:53:37 +00004764bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004765 HeapObject* array = elements();
4766 ASSERT(array != NULL);
4767 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004768}
4769
4770
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004771#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4772bool JSObject::HasExternal##name##Elements() { \
4773 HeapObject* array = elements(); \
4774 ASSERT(array != NULL); \
4775 if (!array->IsHeapObject()) \
4776 return false; \
4777 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004778}
4779
4780
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004781EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4782EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4783EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4784EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4785 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4786EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4787EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4788 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4789EXTERNAL_ELEMENTS_CHECK(Float,
4790 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004791EXTERNAL_ELEMENTS_CHECK(Double,
4792 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004793EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004794
4795
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004796bool JSObject::HasNamedInterceptor() {
4797 return map()->has_named_interceptor();
4798}
4799
4800
4801bool JSObject::HasIndexedInterceptor() {
4802 return map()->has_indexed_interceptor();
4803}
4804
4805
lrn@chromium.org303ada72010-10-27 09:33:13 +00004806MaybeObject* JSObject::EnsureWritableFastElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004807 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004808 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004809 Isolate* isolate = GetIsolate();
4810 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004811 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004812 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4813 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004814 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4815 return maybe_writable_elems;
4816 }
4817 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004818 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004819 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004820 return writable_elems;
4821}
4822
4823
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004824StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004825 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004826 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004827}
4828
4829
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004830SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004831 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004832 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004833}
4834
4835
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004836bool String::IsHashFieldComputed(uint32_t field) {
4837 return (field & kHashNotComputedMask) == 0;
4838}
4839
4840
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004841bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004842 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004843}
4844
4845
4846uint32_t String::Hash() {
4847 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004848 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004849 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004850 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004851 return ComputeAndSetHash();
4852}
4853
4854
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004855StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004856 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004857 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004858 array_index_(0),
4859 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4860 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004861 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004862 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004863}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004864
4865
4866bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004867 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004868}
4869
4870
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004871void StringHasher::AddCharacter(uint32_t c) {
4872 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4873 AddSurrogatePair(c); // Not inlined.
4874 return;
4875 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004876 // Use the Jenkins one-at-a-time hash function to update the hash
4877 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004878 raw_running_hash_ += c;
4879 raw_running_hash_ += (raw_running_hash_ << 10);
4880 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004881 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004882 if (is_array_index_) {
4883 if (c < '0' || c > '9') {
4884 is_array_index_ = false;
4885 } else {
4886 int d = c - '0';
4887 if (is_first_char_) {
4888 is_first_char_ = false;
4889 if (c == '0' && length_ > 1) {
4890 is_array_index_ = false;
4891 return;
4892 }
4893 }
4894 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4895 is_array_index_ = false;
4896 } else {
4897 array_index_ = array_index_ * 10 + d;
4898 }
4899 }
4900 }
4901}
4902
4903
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004904void StringHasher::AddCharacterNoIndex(uint32_t c) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00004905 ASSERT(!is_array_index());
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004906 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4907 AddSurrogatePairNoIndex(c); // Not inlined.
4908 return;
4909 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004910 raw_running_hash_ += c;
4911 raw_running_hash_ += (raw_running_hash_ << 10);
4912 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4913}
4914
4915
4916uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004917 // Get the calculated raw hash value and do some more bit ops to distribute
4918 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004919 uint32_t result = raw_running_hash_;
4920 result += (result << 3);
4921 result ^= (result >> 11);
4922 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004923 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004924 result = 27;
4925 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004926 return result;
4927}
4928
4929
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004930template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004931uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4932 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004933 if (!hasher.has_trivial_hash()) {
4934 int i;
4935 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4936 hasher.AddCharacter(chars[i]);
4937 }
4938 for (; i < length; i++) {
4939 hasher.AddCharacterNoIndex(chars[i]);
4940 }
4941 }
4942 return hasher.GetHashField();
4943}
4944
4945
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004946bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004947 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004948 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4949 return false;
4950 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004951 return SlowAsArrayIndex(index);
4952}
4953
4954
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004955Object* JSReceiver::GetPrototype() {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004956 return map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004957}
4958
4959
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00004960Object* JSReceiver::GetConstructor() {
4961 return map()->constructor();
4962}
4963
4964
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004965bool JSReceiver::HasProperty(String* name) {
4966 if (IsJSProxy()) {
4967 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4968 }
4969 return GetPropertyAttribute(name) != ABSENT;
4970}
4971
4972
4973bool JSReceiver::HasLocalProperty(String* name) {
4974 if (IsJSProxy()) {
4975 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4976 }
4977 return GetLocalPropertyAttribute(name) != ABSENT;
4978}
4979
4980
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004981PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004982 return GetPropertyAttributeWithReceiver(this, key);
4983}
4984
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004985// TODO(504): this may be useful in other places too where JSGlobalProxy
4986// is used.
4987Object* JSObject::BypassGlobalProxy() {
4988 if (IsJSGlobalProxy()) {
4989 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004990 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004991 ASSERT(proto->IsJSGlobalObject());
4992 return proto;
4993 }
4994 return this;
4995}
4996
4997
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004998MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4999 return IsJSProxy()
5000 ? JSProxy::cast(this)->GetIdentityHash(flag)
5001 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005002}
5003
5004
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005005bool JSReceiver::HasElement(uint32_t index) {
5006 if (IsJSProxy()) {
5007 return JSProxy::cast(this)->HasElementWithHandler(index);
5008 }
5009 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005010}
5011
5012
5013bool AccessorInfo::all_can_read() {
5014 return BooleanBit::get(flag(), kAllCanReadBit);
5015}
5016
5017
5018void AccessorInfo::set_all_can_read(bool value) {
5019 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
5020}
5021
5022
5023bool AccessorInfo::all_can_write() {
5024 return BooleanBit::get(flag(), kAllCanWriteBit);
5025}
5026
5027
5028void AccessorInfo::set_all_can_write(bool value) {
5029 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
5030}
5031
5032
ager@chromium.org870a0b62008-11-04 11:43:05 +00005033bool AccessorInfo::prohibits_overwriting() {
5034 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
5035}
5036
5037
5038void AccessorInfo::set_prohibits_overwriting(bool value) {
5039 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
5040}
5041
5042
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005043PropertyAttributes AccessorInfo::property_attributes() {
5044 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
5045}
5046
5047
5048void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00005049 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005050}
5051
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005052
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005053bool AccessorInfo::IsCompatibleReceiver(Object* receiver) {
5054 Object* function_template = expected_receiver_type();
5055 if (!function_template->IsFunctionTemplateInfo()) return true;
5056 return receiver->IsInstanceOf(FunctionTemplateInfo::cast(function_template));
5057}
5058
5059
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005060template<typename Shape, typename Key>
5061void Dictionary<Shape, Key>::SetEntry(int entry,
5062 Object* key,
5063 Object* value) {
5064 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
5065}
5066
5067
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005068template<typename Shape, typename Key>
5069void Dictionary<Shape, Key>::SetEntry(int entry,
5070 Object* key,
5071 Object* value,
5072 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00005073 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005074 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005075 AssertNoAllocation no_gc;
5076 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005077 FixedArray::set(index, key, mode);
5078 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005079 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005080}
5081
5082
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005083bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
5084 ASSERT(other->IsNumber());
5085 return key == static_cast<uint32_t>(other->Number());
5086}
5087
5088
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005089uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
5090 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005091}
5092
5093
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005094uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
5095 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005096 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005097 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005098}
5099
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005100uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
5101 return ComputeIntegerHash(key, seed);
5102}
5103
5104uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
5105 uint32_t seed,
5106 Object* other) {
5107 ASSERT(other->IsNumber());
5108 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
5109}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005110
5111MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
5112 return Isolate::Current()->heap()->NumberFromUint32(key);
5113}
5114
5115
5116bool StringDictionaryShape::IsMatch(String* key, Object* other) {
5117 // We know that all entries in a hash table had their hash keys created.
5118 // Use that knowledge to have fast failure.
5119 if (key->Hash() != String::cast(other)->Hash()) return false;
5120 return key->Equals(String::cast(other));
5121}
5122
5123
5124uint32_t StringDictionaryShape::Hash(String* key) {
5125 return key->Hash();
5126}
5127
5128
5129uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
5130 return String::cast(other)->Hash();
5131}
5132
5133
5134MaybeObject* StringDictionaryShape::AsObject(String* key) {
5135 return key;
5136}
5137
5138
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005139template <int entrysize>
5140bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
5141 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005142}
5143
5144
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005145template <int entrysize>
5146uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005147 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
5148 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005149}
5150
5151
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005152template <int entrysize>
5153uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
5154 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005155 MaybeObject* maybe_hash = other->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>
5161MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005162 return key;
5163}
5164
5165
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005166void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005167 // No write barrier is needed since empty_fixed_array is not in new space.
5168 // Please note this function is used during marking:
5169 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00005170 // - IncrementalMarking::Step
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005171 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
5172 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005173}
5174
5175
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005176void JSArray::EnsureSize(int required_size) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005177 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005178 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005179 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
5180 if (elts->length() < required_size) {
5181 // Doubling in size would be overkill, but leave some slack to avoid
5182 // constantly growing.
5183 Expand(required_size + (required_size >> 3));
5184 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005185 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005186 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
5187 // Expand will allocate a new backing store in new space even if the size
5188 // we asked for isn't larger than what we had before.
5189 Expand(required_size);
5190 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005191}
5192
5193
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005194void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005195 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005196 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
5197}
5198
5199
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005200bool JSArray::AllowsSetElementsLength() {
5201 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
5202 ASSERT(result == !HasExternalArrayElements());
5203 return result;
5204}
5205
5206
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005207MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
5208 MaybeObject* maybe_result = EnsureCanContainElements(
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005209 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005210 if (maybe_result->IsFailure()) return maybe_result;
5211 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005212 IsFastDoubleElementsKind(GetElementsKind())) ||
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005213 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005214 (IsFastObjectElementsKind(GetElementsKind()) ||
5215 (IsFastSmiElementsKind(GetElementsKind()) &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005216 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00005217 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005218 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005219 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005220}
5221
5222
lrn@chromium.org303ada72010-10-27 09:33:13 +00005223MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005224 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005225 return GetHeap()->CopyFixedArray(this);
5226}
5227
5228
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005229MaybeObject* FixedDoubleArray::Copy() {
5230 if (length() == 0) return this;
5231 return GetHeap()->CopyFixedDoubleArray(this);
5232}
5233
5234
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005235void TypeFeedbackCells::SetAstId(int index, Smi* id) {
5236 set(1 + index * 2, id);
5237}
5238
5239
5240Smi* TypeFeedbackCells::AstId(int index) {
5241 return Smi::cast(get(1 + index * 2));
5242}
5243
5244
5245void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
5246 set(index * 2, cell);
5247}
5248
5249
5250JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
5251 return JSGlobalPropertyCell::cast(get(index * 2));
5252}
5253
5254
5255Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
5256 return isolate->factory()->the_hole_value();
5257}
5258
5259
5260Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
5261 return isolate->factory()->undefined_value();
5262}
5263
5264
5265Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
5266 return heap->raw_unchecked_the_hole_value();
5267}
5268
5269
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005270SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00005271SMI_ACCESSORS(TypeFeedbackInfo, ic_with_type_info_count,
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005272 kIcWithTypeinfoCountOffset)
5273ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
5274 kTypeFeedbackCellsOffset)
5275
5276
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00005277SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
5278
5279
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005280Relocatable::Relocatable(Isolate* isolate) {
5281 ASSERT(isolate == Isolate::Current());
5282 isolate_ = isolate;
5283 prev_ = isolate->relocatable_top();
5284 isolate->set_relocatable_top(this);
5285}
5286
5287
5288Relocatable::~Relocatable() {
5289 ASSERT(isolate_ == Isolate::Current());
5290 ASSERT_EQ(isolate_->relocatable_top(), this);
5291 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005292}
5293
5294
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005295int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
5296 return map->instance_size();
5297}
5298
5299
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005300void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005301 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005302 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005303}
5304
5305
5306template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005307void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005308 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005309 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005310}
5311
5312
5313void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
5314 typedef v8::String::ExternalAsciiStringResource Resource;
5315 v->VisitExternalAsciiString(
5316 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5317}
5318
5319
5320template<typename StaticVisitor>
5321void ExternalAsciiString::ExternalAsciiStringIterateBody() {
5322 typedef v8::String::ExternalAsciiStringResource Resource;
5323 StaticVisitor::VisitExternalAsciiString(
5324 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5325}
5326
5327
5328void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
5329 typedef v8::String::ExternalStringResource Resource;
5330 v->VisitExternalTwoByteString(
5331 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5332}
5333
5334
5335template<typename StaticVisitor>
5336void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
5337 typedef v8::String::ExternalStringResource Resource;
5338 StaticVisitor::VisitExternalTwoByteString(
5339 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5340}
5341
5342#define SLOT_ADDR(obj, offset) \
5343 reinterpret_cast<Object**>((obj)->address() + offset)
5344
5345template<int start_offset, int end_offset, int size>
5346void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
5347 HeapObject* obj,
5348 ObjectVisitor* v) {
5349 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
5350}
5351
5352
5353template<int start_offset>
5354void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
5355 int object_size,
5356 ObjectVisitor* v) {
5357 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
5358}
5359
5360#undef SLOT_ADDR
5361
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005362#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005363#undef CAST_ACCESSOR
5364#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005365#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005366#undef ACCESSORS_TO_SMI
5367#undef SMI_ACCESSORS
5368#undef BOOL_GETTER
5369#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005370#undef FIELD_ADDR
5371#undef READ_FIELD
5372#undef WRITE_FIELD
5373#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005374#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005375#undef READ_DOUBLE_FIELD
5376#undef WRITE_DOUBLE_FIELD
5377#undef READ_INT_FIELD
5378#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005379#undef READ_INTPTR_FIELD
5380#undef WRITE_INTPTR_FIELD
5381#undef READ_UINT32_FIELD
5382#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005383#undef READ_SHORT_FIELD
5384#undef WRITE_SHORT_FIELD
5385#undef READ_BYTE_FIELD
5386#undef WRITE_BYTE_FIELD
5387
5388
5389} } // namespace v8::internal
5390
5391#endif // V8_OBJECTS_INL_H_