blob: 4afbe3edd73b472e8690e23be54573f6b7e387bd [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"
50
kasperl@chromium.org71affb52009-05-26 05:44:31 +000051namespace v8 {
52namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000053
54PropertyDetails::PropertyDetails(Smi* smi) {
55 value_ = smi->value();
56}
57
58
59Smi* PropertyDetails::AsSmi() {
60 return Smi::FromInt(value_);
61}
62
63
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000064PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000065 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000066 return PropertyDetails(smi);
67}
68
69
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000070#define TYPE_CHECKER(type, instancetype) \
71 bool Object::Is##type() { \
72 return Object::IsHeapObject() && \
73 HeapObject::cast(this)->map()->instance_type() == instancetype; \
74 }
75
76
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000077#define CAST_ACCESSOR(type) \
78 type* type::cast(Object* object) { \
79 ASSERT(object->Is##type()); \
80 return reinterpret_cast<type*>(object); \
81 }
82
83
84#define INT_ACCESSORS(holder, name, offset) \
85 int holder::name() { return READ_INT_FIELD(this, offset); } \
86 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
87
88
89#define ACCESSORS(holder, name, type, offset) \
90 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000091 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000092 WRITE_FIELD(this, offset, value); \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000093 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000094 }
95
96
rossberg@chromium.org2c067b12012-03-19 11:01:52 +000097// Getter that returns a tagged Smi and setter that writes a tagged Smi.
98#define ACCESSORS_TO_SMI(holder, name, offset) \
99 Smi* holder::name() { return Smi::cast(READ_FIELD(this, offset)); } \
100 void holder::set_##name(Smi* value, WriteBarrierMode mode) { \
101 WRITE_FIELD(this, offset, value); \
102 }
103
104
105// Getter that returns a Smi as an int and writes an int as a Smi.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000106#define SMI_ACCESSORS(holder, name, offset) \
107 int holder::name() { \
108 Object* value = READ_FIELD(this, offset); \
109 return Smi::cast(value)->value(); \
110 } \
111 void holder::set_##name(int value) { \
112 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
113 }
114
115
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000116#define BOOL_GETTER(holder, field, name, offset) \
117 bool holder::name() { \
118 return BooleanBit::get(field(), offset); \
119 } \
120
121
122#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000123 bool holder::name() { \
124 return BooleanBit::get(field(), offset); \
125 } \
126 void holder::set_##name(bool value) { \
127 set_##field(BooleanBit::set(field(), offset, value)); \
128 }
129
130
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000131bool Object::IsFixedArrayBase() {
132 return IsFixedArray() || IsFixedDoubleArray();
133}
134
135
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000136bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
137 // There is a constraint on the object; check.
138 if (!this->IsJSObject()) return false;
139 // Fetch the constructor function of the object.
140 Object* cons_obj = JSObject::cast(this)->map()->constructor();
141 if (!cons_obj->IsJSFunction()) return false;
142 JSFunction* fun = JSFunction::cast(cons_obj);
143 // Iterate through the chain of inheriting function templates to
144 // see if the required one occurs.
145 for (Object* type = fun->shared()->function_data();
146 type->IsFunctionTemplateInfo();
147 type = FunctionTemplateInfo::cast(type)->parent_template()) {
148 if (type == expected) return true;
149 }
150 // Didn't find the required type in the inheritance chain.
151 return false;
152}
153
154
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000155bool Object::IsSmi() {
156 return HAS_SMI_TAG(this);
157}
158
159
160bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000161 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000162}
163
164
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000165bool Object::NonFailureIsHeapObject() {
166 ASSERT(!this->IsFailure());
167 return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0;
168}
169
170
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000171TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000172
173
174bool Object::IsString() {
175 return Object::IsHeapObject()
176 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
177}
178
179
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000180bool Object::IsSpecObject() {
181 return Object::IsHeapObject()
182 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
183}
184
185
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000186bool Object::IsSpecFunction() {
187 if (!Object::IsHeapObject()) return false;
188 InstanceType type = HeapObject::cast(this)->map()->instance_type();
189 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
190}
191
192
ager@chromium.org870a0b62008-11-04 11:43:05 +0000193bool Object::IsSymbol() {
194 if (!this->IsHeapObject()) return false;
195 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000196 // Because the symbol tag is non-zero and no non-string types have the
197 // symbol bit set we can test for symbols with a very simple test
198 // operation.
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000199 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000200 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
201 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000202}
203
204
205bool Object::IsConsString() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000206 if (!IsString()) return false;
207 return StringShape(String::cast(this)).IsCons();
208}
209
210
211bool Object::IsSlicedString() {
212 if (!IsString()) return false;
213 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000214}
215
216
ager@chromium.org870a0b62008-11-04 11:43:05 +0000217bool Object::IsSeqString() {
218 if (!IsString()) return false;
219 return StringShape(String::cast(this)).IsSequential();
220}
221
222
223bool Object::IsSeqAsciiString() {
224 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000225 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000226 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000227}
228
229
230bool Object::IsSeqTwoByteString() {
231 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000232 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000233 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000234}
235
236
237bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000238 if (!IsString()) return false;
239 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000240}
241
242
243bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000244 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000245 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000246 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000247}
248
249
250bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000251 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000252 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000253 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000254}
255
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000256bool Object::HasValidElements() {
257 // Dictionary is covered under FixedArray.
258 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
259}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000260
ager@chromium.org870a0b62008-11-04 11:43:05 +0000261StringShape::StringShape(String* str)
262 : type_(str->map()->instance_type()) {
263 set_valid();
264 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000265}
266
267
ager@chromium.org870a0b62008-11-04 11:43:05 +0000268StringShape::StringShape(Map* map)
269 : type_(map->instance_type()) {
270 set_valid();
271 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000272}
273
274
ager@chromium.org870a0b62008-11-04 11:43:05 +0000275StringShape::StringShape(InstanceType t)
276 : type_(static_cast<uint32_t>(t)) {
277 set_valid();
278 ASSERT((type_ & kIsNotStringMask) == kStringTag);
279}
280
281
282bool StringShape::IsSymbol() {
283 ASSERT(valid());
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000284 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000285 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000286}
287
288
ager@chromium.org5ec48922009-05-05 07:25:34 +0000289bool String::IsAsciiRepresentation() {
290 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000291 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000292}
293
294
ager@chromium.org5ec48922009-05-05 07:25:34 +0000295bool String::IsTwoByteRepresentation() {
296 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000297 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000298}
299
300
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000301bool String::IsAsciiRepresentationUnderneath() {
302 uint32_t type = map()->instance_type();
303 STATIC_ASSERT(kIsIndirectStringTag != 0);
304 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
305 ASSERT(IsFlat());
306 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
307 case kAsciiStringTag:
308 return true;
309 case kTwoByteStringTag:
310 return false;
311 default: // Cons or sliced string. Need to go deeper.
312 return GetUnderlying()->IsAsciiRepresentation();
313 }
314}
315
316
317bool String::IsTwoByteRepresentationUnderneath() {
318 uint32_t type = map()->instance_type();
319 STATIC_ASSERT(kIsIndirectStringTag != 0);
320 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
321 ASSERT(IsFlat());
322 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
323 case kAsciiStringTag:
324 return false;
325 case kTwoByteStringTag:
326 return true;
327 default: // Cons or sliced string. Need to go deeper.
328 return GetUnderlying()->IsTwoByteRepresentation();
329 }
330}
331
332
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000333bool String::HasOnlyAsciiChars() {
334 uint32_t type = map()->instance_type();
335 return (type & kStringEncodingMask) == kAsciiStringTag ||
336 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000337}
338
339
ager@chromium.org870a0b62008-11-04 11:43:05 +0000340bool StringShape::IsCons() {
341 return (type_ & kStringRepresentationMask) == kConsStringTag;
342}
343
344
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000345bool StringShape::IsSliced() {
346 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
347}
348
349
350bool StringShape::IsIndirect() {
351 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
352}
353
354
ager@chromium.org870a0b62008-11-04 11:43:05 +0000355bool StringShape::IsExternal() {
356 return (type_ & kStringRepresentationMask) == kExternalStringTag;
357}
358
359
360bool StringShape::IsSequential() {
361 return (type_ & kStringRepresentationMask) == kSeqStringTag;
362}
363
364
365StringRepresentationTag StringShape::representation_tag() {
366 uint32_t tag = (type_ & kStringRepresentationMask);
367 return static_cast<StringRepresentationTag>(tag);
368}
369
370
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000371uint32_t StringShape::encoding_tag() {
372 return type_ & kStringEncodingMask;
373}
374
375
ager@chromium.org870a0b62008-11-04 11:43:05 +0000376uint32_t StringShape::full_representation_tag() {
377 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
378}
379
380
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000381STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
382 Internals::kFullStringRepresentationMask);
383
384
ager@chromium.org870a0b62008-11-04 11:43:05 +0000385bool StringShape::IsSequentialAscii() {
386 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
387}
388
389
390bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000391 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000392}
393
394
395bool StringShape::IsExternalAscii() {
396 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
397}
398
399
400bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000401 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000402}
403
404
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000405STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
406 Internals::kExternalTwoByteRepresentationTag);
407
408
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000409uc32 FlatStringReader::Get(int index) {
410 ASSERT(0 <= index && index <= length_);
411 if (is_ascii_) {
412 return static_cast<const byte*>(start_)[index];
413 } else {
414 return static_cast<const uc16*>(start_)[index];
415 }
416}
417
418
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000419bool Object::IsNumber() {
420 return IsSmi() || IsHeapNumber();
421}
422
423
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000424TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
425TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000426
427
428bool Object::IsFiller() {
429 if (!Object::IsHeapObject()) return false;
430 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
431 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
432}
433
434
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000435TYPE_CHECKER(ExternalPixelArray, EXTERNAL_PIXEL_ARRAY_TYPE)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000436
437
ager@chromium.org3811b432009-10-28 14:53:37 +0000438bool Object::IsExternalArray() {
439 if (!Object::IsHeapObject())
440 return false;
441 InstanceType instance_type =
442 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000443 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
444 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000445}
446
447
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000448TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE)
449TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
450TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE)
451TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
452TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE)
453TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
454TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE)
455TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000456
457
lrn@chromium.org303ada72010-10-27 09:33:13 +0000458bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000459 return HAS_FAILURE_TAG(this);
460}
461
462
lrn@chromium.org303ada72010-10-27 09:33:13 +0000463bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000464 return HAS_FAILURE_TAG(this)
465 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
466}
467
468
lrn@chromium.org303ada72010-10-27 09:33:13 +0000469bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000470 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000471 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000472}
473
474
lrn@chromium.org303ada72010-10-27 09:33:13 +0000475bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000476 return this == Failure::Exception();
477}
478
479
lrn@chromium.org303ada72010-10-27 09:33:13 +0000480bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000481 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000482}
483
484
485Failure* Failure::cast(MaybeObject* obj) {
486 ASSERT(HAS_FAILURE_TAG(obj));
487 return reinterpret_cast<Failure*>(obj);
488}
489
490
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000491bool Object::IsJSReceiver() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000492 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000493 return IsHeapObject() &&
494 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
495}
496
497
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000498bool Object::IsJSObject() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000499 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
500 return IsHeapObject() &&
501 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000502}
503
504
505bool Object::IsJSProxy() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000506 if (!Object::IsHeapObject()) return false;
507 InstanceType type = HeapObject::cast(this)->map()->instance_type();
508 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000509}
510
511
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000512TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
513TYPE_CHECKER(JSSet, JS_SET_TYPE)
514TYPE_CHECKER(JSMap, JS_MAP_TYPE)
515TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
516TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
517TYPE_CHECKER(Map, MAP_TYPE)
518TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
519TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000520
521
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000522bool Object::IsDescriptorArray() {
523 return IsFixedArray();
524}
525
526
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000527bool Object::IsDeoptimizationInputData() {
528 // Must be a fixed array.
529 if (!IsFixedArray()) return false;
530
531 // There's no sure way to detect the difference between a fixed array and
532 // a deoptimization data array. Since this is used for asserts we can
533 // check that the length is zero or else the fixed size plus a multiple of
534 // the entry size.
535 int length = FixedArray::cast(this)->length();
536 if (length == 0) return true;
537
538 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
539 return length >= 0 &&
540 length % DeoptimizationInputData::kDeoptEntrySize == 0;
541}
542
543
544bool Object::IsDeoptimizationOutputData() {
545 if (!IsFixedArray()) return false;
546 // There's actually no way to see the difference between a fixed array and
547 // a deoptimization data array. Since this is used for asserts we can check
548 // that the length is plausible though.
549 if (FixedArray::cast(this)->length() % 2 != 0) return false;
550 return true;
551}
552
553
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000554bool Object::IsTypeFeedbackCells() {
555 if (!IsFixedArray()) return false;
556 // There's actually no way to see the difference between a fixed array and
557 // a cache cells array. Since this is used for asserts we can check that
558 // the length is plausible though.
559 if (FixedArray::cast(this)->length() % 2 != 0) return false;
560 return true;
561}
562
563
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000564bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000565 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000566 Map* map = HeapObject::cast(this)->map();
567 Heap* heap = map->GetHeap();
568 return (map == heap->function_context_map() ||
569 map == heap->catch_context_map() ||
570 map == heap->with_context_map() ||
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000571 map == heap->global_context_map() ||
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000572 map == heap->block_context_map() ||
573 map == heap->module_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000574 }
575 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000576}
577
578
579bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000580 return Object::IsHeapObject() &&
581 HeapObject::cast(this)->map() ==
582 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000583}
584
585
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000586bool Object::IsModuleContext() {
587 return Object::IsHeapObject() &&
588 HeapObject::cast(this)->map() ==
589 HeapObject::cast(this)->GetHeap()->module_context_map();
590}
591
592
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000593bool Object::IsScopeInfo() {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000594 return Object::IsHeapObject() &&
595 HeapObject::cast(this)->map() ==
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000596 HeapObject::cast(this)->GetHeap()->scope_info_map();
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000597}
598
599
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000600TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000601
602
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000603template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000604 return obj->IsJSFunction();
605}
606
607
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000608TYPE_CHECKER(Code, CODE_TYPE)
609TYPE_CHECKER(Oddball, ODDBALL_TYPE)
610TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
611TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000612TYPE_CHECKER(JSModule, JS_MODULE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000613TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000614TYPE_CHECKER(JSDate, JS_DATE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000615TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000616
617
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000618bool Object::IsStringWrapper() {
619 return IsJSValue() && JSValue::cast(this)->value()->IsString();
620}
621
622
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000623TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000624
625
626bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000627 return IsOddball() &&
628 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000629}
630
631
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000632TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
633TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000634
635
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000636template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000637 return obj->IsJSArray();
638}
639
640
641bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000642 return Object::IsHeapObject() &&
643 HeapObject::cast(this)->map() ==
644 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000645}
646
647
648bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000649 return IsHashTable() &&
650 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000651}
652
653
654bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000655 return IsHashTable() && this ==
656 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000657}
658
659
ager@chromium.orgac091b72010-05-05 07:34:42 +0000660bool Object::IsJSFunctionResultCache() {
661 if (!IsFixedArray()) return false;
662 FixedArray* self = FixedArray::cast(this);
663 int length = self->length();
664 if (length < JSFunctionResultCache::kEntriesIndex) return false;
665 if ((length - JSFunctionResultCache::kEntriesIndex)
666 % JSFunctionResultCache::kEntrySize != 0) {
667 return false;
668 }
669#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000670 if (FLAG_verify_heap) {
671 reinterpret_cast<JSFunctionResultCache*>(this)->
672 JSFunctionResultCacheVerify();
673 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000674#endif
675 return true;
676}
677
678
ricow@chromium.org65fae842010-08-25 15:26:24 +0000679bool Object::IsNormalizedMapCache() {
680 if (!IsFixedArray()) return false;
681 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
682 return false;
683 }
684#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000685 if (FLAG_verify_heap) {
686 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
687 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000688#endif
689 return true;
690}
691
692
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000693bool Object::IsCompilationCacheTable() {
694 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000695}
696
697
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000698bool Object::IsCodeCacheHashTable() {
699 return IsHashTable();
700}
701
702
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000703bool Object::IsPolymorphicCodeCacheHashTable() {
704 return IsHashTable();
705}
706
707
ager@chromium.org236ad962008-09-25 09:45:57 +0000708bool Object::IsMapCache() {
709 return IsHashTable();
710}
711
712
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000713bool Object::IsPrimitive() {
714 return IsOddball() || IsNumber() || IsString();
715}
716
717
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000718bool Object::IsJSGlobalProxy() {
719 bool result = IsHeapObject() &&
720 (HeapObject::cast(this)->map()->instance_type() ==
721 JS_GLOBAL_PROXY_TYPE);
722 ASSERT(!result || IsAccessCheckNeeded());
723 return result;
724}
725
726
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000727bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000728 if (!IsHeapObject()) return false;
729
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000730 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000731 return type == JS_GLOBAL_OBJECT_TYPE ||
732 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000733}
734
735
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000736TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
737TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000738
739
740bool Object::IsUndetectableObject() {
741 return IsHeapObject()
742 && HeapObject::cast(this)->map()->is_undetectable();
743}
744
745
746bool Object::IsAccessCheckNeeded() {
747 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000748 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000749}
750
751
752bool Object::IsStruct() {
753 if (!IsHeapObject()) return false;
754 switch (HeapObject::cast(this)->map()->instance_type()) {
755#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
756 STRUCT_LIST(MAKE_STRUCT_CASE)
757#undef MAKE_STRUCT_CASE
758 default: return false;
759 }
760}
761
762
763#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
764 bool Object::Is##Name() { \
765 return Object::IsHeapObject() \
766 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
767 }
768 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
769#undef MAKE_STRUCT_PREDICATE
770
771
772bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000773 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000774}
775
776
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000777bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000778 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
779}
780
781
782bool Object::IsTheHole() {
783 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000784}
785
786
787bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000788 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000789}
790
791
792bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000793 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000794}
795
796
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000797bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000798 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000799}
800
801
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000802double Object::Number() {
803 ASSERT(IsNumber());
804 return IsSmi()
805 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
806 : reinterpret_cast<HeapNumber*>(this)->value();
807}
808
809
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000810bool Object::IsNaN() {
811 return this->IsHeapNumber() && isnan(HeapNumber::cast(this)->value());
812}
813
814
lrn@chromium.org303ada72010-10-27 09:33:13 +0000815MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000816 if (IsSmi()) return this;
817 if (IsHeapNumber()) {
818 double value = HeapNumber::cast(this)->value();
819 int int_value = FastD2I(value);
820 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
821 return Smi::FromInt(int_value);
822 }
823 }
824 return Failure::Exception();
825}
826
827
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000828bool Object::HasSpecificClassOf(String* name) {
829 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
830}
831
832
lrn@chromium.org303ada72010-10-27 09:33:13 +0000833MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000834 // GetElement can trigger a getter which can cause allocation.
835 // This was not always the case. This ASSERT is here to catch
836 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000837 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000838 return GetElementWithReceiver(this, index);
839}
840
841
lrn@chromium.org303ada72010-10-27 09:33:13 +0000842Object* Object::GetElementNoExceptionThrown(uint32_t index) {
843 MaybeObject* maybe = GetElementWithReceiver(this, index);
844 ASSERT(!maybe->IsFailure());
845 Object* result = NULL; // Initialization to please compiler.
846 maybe->ToObject(&result);
847 return result;
848}
849
850
851MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000852 PropertyAttributes attributes;
853 return GetPropertyWithReceiver(this, key, &attributes);
854}
855
856
lrn@chromium.org303ada72010-10-27 09:33:13 +0000857MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000858 return GetPropertyWithReceiver(this, key, attributes);
859}
860
861
862#define FIELD_ADDR(p, offset) \
863 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
864
865#define READ_FIELD(p, offset) \
866 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
867
868#define WRITE_FIELD(p, offset, value) \
869 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
870
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000871#define WRITE_BARRIER(heap, object, offset, value) \
872 heap->incremental_marking()->RecordWrite( \
873 object, HeapObject::RawField(object, offset), value); \
874 if (heap->InNewSpace(value)) { \
875 heap->RecordWrite(object->address(), offset); \
876 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000877
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000878#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
879 if (mode == UPDATE_WRITE_BARRIER) { \
880 heap->incremental_marking()->RecordWrite( \
881 object, HeapObject::RawField(object, offset), value); \
882 if (heap->InNewSpace(value)) { \
883 heap->RecordWrite(object->address(), offset); \
884 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000885 }
886
lrn@chromium.org7516f052011-03-30 08:52:27 +0000887#ifndef V8_TARGET_ARCH_MIPS
888 #define READ_DOUBLE_FIELD(p, offset) \
889 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
890#else // V8_TARGET_ARCH_MIPS
891 // Prevent gcc from using load-double (mips ldc1) on (possibly)
892 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000893 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000894 union conversion {
895 double d;
896 uint32_t u[2];
897 } c;
898 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
899 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
900 return c.d;
901 }
902 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
903#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000904
lrn@chromium.org7516f052011-03-30 08:52:27 +0000905#ifndef V8_TARGET_ARCH_MIPS
906 #define WRITE_DOUBLE_FIELD(p, offset, value) \
907 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
908#else // V8_TARGET_ARCH_MIPS
909 // Prevent gcc from using store-double (mips sdc1) on (possibly)
910 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000911 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000912 double value) {
913 union conversion {
914 double d;
915 uint32_t u[2];
916 } c;
917 c.d = value;
918 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
919 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
920 }
921 #define WRITE_DOUBLE_FIELD(p, offset, value) \
922 write_double_field(p, offset, value)
923#endif // V8_TARGET_ARCH_MIPS
924
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000925
926#define READ_INT_FIELD(p, offset) \
927 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
928
929#define WRITE_INT_FIELD(p, offset, value) \
930 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
931
ager@chromium.org3e875802009-06-29 08:26:34 +0000932#define READ_INTPTR_FIELD(p, offset) \
933 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
934
935#define WRITE_INTPTR_FIELD(p, offset, value) \
936 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
937
ager@chromium.org7c537e22008-10-16 08:43:32 +0000938#define READ_UINT32_FIELD(p, offset) \
939 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
940
941#define WRITE_UINT32_FIELD(p, offset, value) \
942 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
943
danno@chromium.org88aa0582012-03-23 15:11:57 +0000944#define READ_INT64_FIELD(p, offset) \
945 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)))
946
947#define WRITE_INT64_FIELD(p, offset, value) \
948 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
949
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000950#define READ_SHORT_FIELD(p, offset) \
951 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
952
953#define WRITE_SHORT_FIELD(p, offset, value) \
954 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
955
956#define READ_BYTE_FIELD(p, offset) \
957 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
958
959#define WRITE_BYTE_FIELD(p, offset, value) \
960 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
961
962
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000963Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
964 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000965}
966
967
968int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000969 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000970}
971
972
973Smi* Smi::FromInt(int value) {
974 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000975 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000976 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000977 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000978 return reinterpret_cast<Smi*>(tagged_value);
979}
980
981
982Smi* Smi::FromIntptr(intptr_t value) {
983 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000984 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
985 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000986}
987
988
989Failure::Type Failure::type() const {
990 return static_cast<Type>(value() & kFailureTypeTagMask);
991}
992
993
994bool Failure::IsInternalError() const {
995 return type() == INTERNAL_ERROR;
996}
997
998
999bool Failure::IsOutOfMemoryException() const {
1000 return type() == OUT_OF_MEMORY_EXCEPTION;
1001}
1002
1003
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001004AllocationSpace Failure::allocation_space() const {
1005 ASSERT_EQ(RETRY_AFTER_GC, type());
1006 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1007 & kSpaceTagMask);
1008}
1009
1010
1011Failure* Failure::InternalError() {
1012 return Construct(INTERNAL_ERROR);
1013}
1014
1015
1016Failure* Failure::Exception() {
1017 return Construct(EXCEPTION);
1018}
1019
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001020
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001021Failure* Failure::OutOfMemoryException() {
1022 return Construct(OUT_OF_MEMORY_EXCEPTION);
1023}
1024
1025
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001026intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001027 return static_cast<intptr_t>(
1028 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001029}
1030
1031
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001032Failure* Failure::RetryAfterGC() {
1033 return RetryAfterGC(NEW_SPACE);
1034}
1035
1036
1037Failure* Failure::RetryAfterGC(AllocationSpace space) {
1038 ASSERT((space & ~kSpaceTagMask) == 0);
1039 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001040}
1041
1042
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001043Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001044 uintptr_t info =
1045 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001046 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001047 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001048}
1049
1050
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001051bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001052#ifdef DEBUG
1053 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1054#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001055
1056#ifdef V8_TARGET_ARCH_X64
1057 // To be representable as a long smi, the value must be a 32-bit integer.
1058 bool result = (value == static_cast<int32_t>(value));
1059#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001060 // To be representable as an tagged small integer, the two
1061 // most-significant bits of 'value' must be either 00 or 11 due to
1062 // sign-extension. To check this we add 01 to the two
1063 // most-significant bits, and check if the most-significant bit is 0
1064 //
1065 // CAUTION: The original code below:
1066 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1067 // may lead to incorrect results according to the C language spec, and
1068 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1069 // compiler may produce undefined results in case of signed integer
1070 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001071 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001072#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001073 ASSERT(result == in_range);
1074 return result;
1075}
1076
1077
kasper.lund7276f142008-07-30 08:49:36 +00001078MapWord MapWord::FromMap(Map* map) {
1079 return MapWord(reinterpret_cast<uintptr_t>(map));
1080}
1081
1082
1083Map* MapWord::ToMap() {
1084 return reinterpret_cast<Map*>(value_);
1085}
1086
1087
1088bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001089 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001090}
1091
1092
1093MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001094 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1095 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001096}
1097
1098
1099HeapObject* MapWord::ToForwardingAddress() {
1100 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001101 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001102}
1103
1104
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001105#ifdef DEBUG
1106void HeapObject::VerifyObjectField(int offset) {
1107 VerifyPointer(READ_FIELD(this, offset));
1108}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001109
1110void HeapObject::VerifySmiField(int offset) {
1111 ASSERT(READ_FIELD(this, offset)->IsSmi());
1112}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001113#endif
1114
1115
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001116Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001117 Heap* heap =
1118 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1119 ASSERT(heap != NULL);
1120 ASSERT(heap->isolate() == Isolate::Current());
1121 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001122}
1123
1124
1125Isolate* HeapObject::GetIsolate() {
1126 return GetHeap()->isolate();
1127}
1128
1129
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001130Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001131 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001132}
1133
1134
1135void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001136 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001137 if (value != NULL) {
1138 // TODO(1600) We are passing NULL as a slot because maps can never be on
1139 // evacuation candidate.
1140 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1141 }
1142}
1143
1144
1145// Unsafe accessor omitting write barrier.
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001146void HeapObject::set_map_no_write_barrier(Map* value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001147 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001148}
1149
1150
kasper.lund7276f142008-07-30 08:49:36 +00001151MapWord HeapObject::map_word() {
1152 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1153}
1154
1155
1156void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001157 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001158 // here.
1159 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1160}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001161
1162
1163HeapObject* HeapObject::FromAddress(Address address) {
1164 ASSERT_TAG_ALIGNED(address);
1165 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1166}
1167
1168
1169Address HeapObject::address() {
1170 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1171}
1172
1173
1174int HeapObject::Size() {
1175 return SizeFromMap(map());
1176}
1177
1178
1179void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1180 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1181 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1182}
1183
1184
1185void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1186 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1187}
1188
1189
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001190double HeapNumber::value() {
1191 return READ_DOUBLE_FIELD(this, kValueOffset);
1192}
1193
1194
1195void HeapNumber::set_value(double value) {
1196 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1197}
1198
1199
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001200int HeapNumber::get_exponent() {
1201 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1202 kExponentShift) - kExponentBias;
1203}
1204
1205
1206int HeapNumber::get_sign() {
1207 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1208}
1209
1210
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001211ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001212
1213
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001214Object** FixedArray::GetFirstElementAddress() {
1215 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1216}
1217
1218
1219bool FixedArray::ContainsOnlySmisOrHoles() {
1220 Object* the_hole = GetHeap()->the_hole_value();
1221 Object** current = GetFirstElementAddress();
1222 for (int i = 0; i < length(); ++i) {
1223 Object* candidate = *current++;
1224 if (!candidate->IsSmi() && candidate != the_hole) return false;
1225 }
1226 return true;
1227}
1228
1229
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001230FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001231 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001232 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001233}
1234
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001235
1236void JSObject::ValidateElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001237#if DEBUG
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001238 if (FLAG_enable_slow_asserts) {
1239 ElementsAccessor* accessor = GetElementsAccessor();
1240 accessor->Validate(this);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001241 }
1242#endif
1243}
1244
1245
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001246MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001247 ValidateElements();
1248 ElementsKind elements_kind = map()->elements_kind();
1249 if (!IsFastObjectElementsKind(elements_kind)) {
1250 if (IsFastHoleyElementsKind(elements_kind)) {
1251 return TransitionElementsKind(FAST_HOLEY_ELEMENTS);
1252 } else {
1253 return TransitionElementsKind(FAST_ELEMENTS);
1254 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001255 }
1256 return this;
1257}
1258
1259
1260MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001261 uint32_t count,
1262 EnsureElementsMode mode) {
1263 ElementsKind current_kind = map()->elements_kind();
1264 ElementsKind target_kind = current_kind;
1265 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001266 bool is_holey = IsFastHoleyElementsKind(current_kind);
1267 if (current_kind == FAST_HOLEY_ELEMENTS) return this;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001268 Heap* heap = GetHeap();
1269 Object* the_hole = heap->the_hole_value();
1270 Object* heap_number_map = heap->heap_number_map();
1271 for (uint32_t i = 0; i < count; ++i) {
1272 Object* current = *objects++;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001273 if (current == the_hole) {
1274 is_holey = true;
1275 target_kind = GetHoleyElementsKind(target_kind);
1276 } else if (!current->IsSmi()) {
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001277 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001278 HeapObject::cast(current)->map() == heap_number_map &&
1279 IsFastSmiElementsKind(target_kind)) {
1280 if (is_holey) {
1281 target_kind = FAST_HOLEY_DOUBLE_ELEMENTS;
1282 } else {
1283 target_kind = FAST_DOUBLE_ELEMENTS;
1284 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001285 } else {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001286 if (!current->IsNumber()) {
1287 if (is_holey) {
1288 target_kind = FAST_HOLEY_ELEMENTS;
1289 break;
1290 } else {
1291 target_kind = FAST_ELEMENTS;
1292 }
1293 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001294 }
1295 }
1296 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001297
1298 if (target_kind != current_kind) {
1299 return TransitionElementsKind(target_kind);
1300 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001301 return this;
1302}
1303
1304
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001305MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001306 uint32_t length,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001307 EnsureElementsMode mode) {
1308 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1309 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1310 elements->map() == GetHeap()->fixed_cow_array_map());
1311 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1312 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1313 }
1314 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001315 return EnsureCanContainElements(objects, length, mode);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001316 }
1317
1318 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001319 if (GetElementsKind() == FAST_HOLEY_SMI_ELEMENTS) {
1320 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS);
1321 } else if (GetElementsKind() == FAST_SMI_ELEMENTS) {
1322 FixedDoubleArray* double_array = FixedDoubleArray::cast(elements);
1323 for (uint32_t i = 0; i < length; ++i) {
1324 if (double_array->is_the_hole(i)) {
1325 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS);
1326 }
1327 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001328 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1329 }
1330
1331 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001332}
1333
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001334
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001335MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
1336 ElementsKind to_kind) {
1337 Map* current_map = map();
1338 ElementsKind from_kind = current_map->elements_kind();
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001339 if (from_kind == to_kind) return current_map;
1340
1341 Context* global_context = isolate->context()->global_context();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001342 Object* maybe_array_maps = global_context->js_array_maps();
1343 if (maybe_array_maps->IsFixedArray()) {
1344 FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
1345 if (array_maps->get(from_kind) == current_map) {
1346 Object* maybe_transitioned_map = array_maps->get(to_kind);
1347 if (maybe_transitioned_map->IsMap()) {
1348 return Map::cast(maybe_transitioned_map);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001349 }
1350 }
1351 }
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001352
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001353 return GetElementsTransitionMapSlow(to_kind);
1354}
1355
1356
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001357void JSObject::set_map_and_elements(Map* new_map,
1358 FixedArrayBase* value,
1359 WriteBarrierMode mode) {
1360 ASSERT(value->HasValidElements());
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001361 if (new_map != NULL) {
1362 if (mode == UPDATE_WRITE_BARRIER) {
1363 set_map(new_map);
1364 } else {
1365 ASSERT(mode == SKIP_WRITE_BARRIER);
1366 set_map_no_write_barrier(new_map);
1367 }
1368 }
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001369 ASSERT((map()->has_fast_smi_or_object_elements() ||
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001370 (value == GetHeap()->empty_fixed_array())) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001371 (value->map() == GetHeap()->fixed_array_map() ||
1372 value->map() == GetHeap()->fixed_cow_array_map()));
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001373 ASSERT((value == GetHeap()->empty_fixed_array()) ||
1374 (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001375 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001376 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001377}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001378
1379
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001380void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1381 set_map_and_elements(NULL, value, mode);
1382}
1383
1384
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001385void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001386 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1387 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001388}
1389
1390
1391void JSObject::initialize_elements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001392 ASSERT(map()->has_fast_smi_or_object_elements() ||
danno@chromium.org2c26cb12012-05-03 09:06:43 +00001393 map()->has_fast_double_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001394 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1395 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001396}
1397
1398
lrn@chromium.org303ada72010-10-27 09:33:13 +00001399MaybeObject* JSObject::ResetElements() {
1400 Object* obj;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001401 ElementsKind elements_kind = GetInitialFastElementsKind();
1402 if (!FLAG_smi_only_arrays) {
1403 elements_kind = FastSmiToObjectElementsKind(elements_kind);
1404 }
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001405 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(),
1406 elements_kind);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001407 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001408 set_map(Map::cast(obj));
1409 initialize_elements();
1410 return this;
1411}
1412
1413
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001414ACCESSORS(Oddball, to_string, String, kToStringOffset)
1415ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1416
1417
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001418byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001419 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001420}
1421
1422
1423void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001424 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001425}
1426
1427
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001428Object* JSGlobalPropertyCell::value() {
1429 return READ_FIELD(this, kValueOffset);
1430}
1431
1432
1433void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1434 // The write barrier is not used for global property cells.
1435 ASSERT(!val->IsJSGlobalPropertyCell());
1436 WRITE_FIELD(this, kValueOffset, val);
1437}
1438
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001439
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001440int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001441 InstanceType type = map()->instance_type();
1442 // Check for the most common kind of JavaScript object before
1443 // falling into the generic switch. This speeds up the internal
1444 // field operations considerably on average.
1445 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1446 switch (type) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001447 case JS_MODULE_TYPE:
1448 return JSModule::kSize;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001449 case JS_GLOBAL_PROXY_TYPE:
1450 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001451 case JS_GLOBAL_OBJECT_TYPE:
1452 return JSGlobalObject::kSize;
1453 case JS_BUILTINS_OBJECT_TYPE:
1454 return JSBuiltinsObject::kSize;
1455 case JS_FUNCTION_TYPE:
1456 return JSFunction::kSize;
1457 case JS_VALUE_TYPE:
1458 return JSValue::kSize;
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00001459 case JS_DATE_TYPE:
1460 return JSDate::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001461 case JS_ARRAY_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001462 return JSArray::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001463 case JS_WEAK_MAP_TYPE:
1464 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001465 case JS_REGEXP_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001466 return JSRegExp::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001467 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001468 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001469 case JS_MESSAGE_OBJECT_TYPE:
1470 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001471 default:
1472 UNREACHABLE();
1473 return 0;
1474 }
1475}
1476
1477
1478int JSObject::GetInternalFieldCount() {
1479 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001480 // Make sure to adjust for the number of in-object properties. These
1481 // properties do contribute to the size, but are not internal fields.
1482 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1483 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001484}
1485
1486
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001487int JSObject::GetInternalFieldOffset(int index) {
1488 ASSERT(index < GetInternalFieldCount() && index >= 0);
1489 return GetHeaderSize() + (kPointerSize * index);
1490}
1491
1492
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001493Object* JSObject::GetInternalField(int index) {
1494 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001495 // Internal objects do follow immediately after the header, whereas in-object
1496 // properties are at the end of the object. Therefore there is no need
1497 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001498 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1499}
1500
1501
1502void JSObject::SetInternalField(int index, Object* value) {
1503 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001504 // Internal objects do follow immediately after the header, whereas in-object
1505 // properties are at the end of the object. Therefore there is no need
1506 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001507 int offset = GetHeaderSize() + (kPointerSize * index);
1508 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001509 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001510}
1511
1512
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001513void JSObject::SetInternalField(int index, Smi* value) {
1514 ASSERT(index < GetInternalFieldCount() && index >= 0);
1515 // Internal objects do follow immediately after the header, whereas in-object
1516 // properties are at the end of the object. Therefore there is no need
1517 // to adjust the index here.
1518 int offset = GetHeaderSize() + (kPointerSize * index);
1519 WRITE_FIELD(this, offset, value);
1520}
1521
1522
ager@chromium.org7c537e22008-10-16 08:43:32 +00001523// Access fast-case object properties at index. The use of these routines
1524// is needed to correctly distinguish between properties stored in-object and
1525// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001526Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001527 // Adjust for the number of properties stored in the object.
1528 index -= map()->inobject_properties();
1529 if (index < 0) {
1530 int offset = map()->instance_size() + (index * kPointerSize);
1531 return READ_FIELD(this, offset);
1532 } else {
1533 ASSERT(index < properties()->length());
1534 return properties()->get(index);
1535 }
1536}
1537
1538
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001539Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001540 // Adjust for the number of properties stored in the object.
1541 index -= map()->inobject_properties();
1542 if (index < 0) {
1543 int offset = map()->instance_size() + (index * kPointerSize);
1544 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001545 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001546 } else {
1547 ASSERT(index < properties()->length());
1548 properties()->set(index, value);
1549 }
1550 return value;
1551}
1552
1553
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001554int JSObject::GetInObjectPropertyOffset(int index) {
1555 // Adjust for the number of properties stored in the object.
1556 index -= map()->inobject_properties();
1557 ASSERT(index < 0);
1558 return map()->instance_size() + (index * kPointerSize);
1559}
1560
1561
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001562Object* JSObject::InObjectPropertyAt(int index) {
1563 // Adjust for the number of properties stored in the object.
1564 index -= map()->inobject_properties();
1565 ASSERT(index < 0);
1566 int offset = map()->instance_size() + (index * kPointerSize);
1567 return READ_FIELD(this, offset);
1568}
1569
1570
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001571Object* JSObject::InObjectPropertyAtPut(int index,
1572 Object* value,
1573 WriteBarrierMode mode) {
1574 // Adjust for the number of properties stored in the object.
1575 index -= map()->inobject_properties();
1576 ASSERT(index < 0);
1577 int offset = map()->instance_size() + (index * kPointerSize);
1578 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001579 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001580 return value;
1581}
1582
1583
1584
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001585void JSObject::InitializeBody(Map* map,
1586 Object* pre_allocated_value,
1587 Object* filler_value) {
1588 ASSERT(!filler_value->IsHeapObject() ||
1589 !GetHeap()->InNewSpace(filler_value));
1590 ASSERT(!pre_allocated_value->IsHeapObject() ||
1591 !GetHeap()->InNewSpace(pre_allocated_value));
1592 int size = map->instance_size();
1593 int offset = kHeaderSize;
1594 if (filler_value != pre_allocated_value) {
1595 int pre_allocated = map->pre_allocated_property_fields();
1596 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1597 for (int i = 0; i < pre_allocated; i++) {
1598 WRITE_FIELD(this, offset, pre_allocated_value);
1599 offset += kPointerSize;
1600 }
1601 }
1602 while (offset < size) {
1603 WRITE_FIELD(this, offset, filler_value);
1604 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001605 }
1606}
1607
1608
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001609bool JSObject::HasFastProperties() {
1610 return !properties()->IsDictionary();
1611}
1612
1613
1614int JSObject::MaxFastProperties() {
1615 // Allow extra fast properties if the object has more than
1616 // kMaxFastProperties in-object properties. When this is the case,
1617 // it is very unlikely that the object is being used as a dictionary
1618 // and there is a good chance that allowing more map transitions
1619 // will be worth it.
1620 return Max(map()->inobject_properties(), kMaxFastProperties);
1621}
1622
1623
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001624void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001625 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001626 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001627 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001628 }
1629}
1630
1631
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001632bool Object::ToArrayIndex(uint32_t* index) {
1633 if (IsSmi()) {
1634 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001635 if (value < 0) return false;
1636 *index = value;
1637 return true;
1638 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001639 if (IsHeapNumber()) {
1640 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001641 uint32_t uint_value = static_cast<uint32_t>(value);
1642 if (value == static_cast<double>(uint_value)) {
1643 *index = uint_value;
1644 return true;
1645 }
1646 }
1647 return false;
1648}
1649
1650
1651bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1652 if (!this->IsJSValue()) return false;
1653
1654 JSValue* js_value = JSValue::cast(this);
1655 if (!js_value->value()->IsString()) return false;
1656
1657 String* str = String::cast(js_value->value());
1658 if (index >= (uint32_t)str->length()) return false;
1659
1660 return true;
1661}
1662
1663
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001664FixedArrayBase* FixedArrayBase::cast(Object* object) {
1665 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1666 return reinterpret_cast<FixedArrayBase*>(object);
1667}
1668
1669
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001670Object* FixedArray::get(int index) {
1671 ASSERT(index >= 0 && index < this->length());
1672 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1673}
1674
1675
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001676bool FixedArray::is_the_hole(int index) {
1677 return get(index) == GetHeap()->the_hole_value();
1678}
1679
1680
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001681void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001682 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001683 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001684 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1685 int offset = kHeaderSize + index * kPointerSize;
1686 WRITE_FIELD(this, offset, value);
1687}
1688
1689
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001690void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001691 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001692 ASSERT(index >= 0 && index < this->length());
1693 int offset = kHeaderSize + index * kPointerSize;
1694 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001695 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001696}
1697
1698
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001699inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1700 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1701}
1702
1703
1704inline double FixedDoubleArray::hole_nan_as_double() {
1705 return BitCast<double, uint64_t>(kHoleNanInt64);
1706}
1707
1708
1709inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1710 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1711 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1712 return OS::nan_value();
1713}
1714
1715
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001716double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001717 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1718 map() != HEAP->fixed_array_map());
1719 ASSERT(index >= 0 && index < this->length());
1720 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1721 ASSERT(!is_the_hole_nan(result));
1722 return result;
1723}
1724
danno@chromium.org88aa0582012-03-23 15:11:57 +00001725int64_t FixedDoubleArray::get_representation(int index) {
1726 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1727 map() != HEAP->fixed_array_map());
1728 ASSERT(index >= 0 && index < this->length());
1729 return READ_INT64_FIELD(this, kHeaderSize + index * kDoubleSize);
1730}
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001731
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001732MaybeObject* FixedDoubleArray::get(int index) {
1733 if (is_the_hole(index)) {
1734 return GetHeap()->the_hole_value();
1735 } else {
1736 return GetHeap()->NumberFromDouble(get_scalar(index));
1737 }
1738}
1739
1740
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001741void FixedDoubleArray::set(int index, double value) {
1742 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1743 map() != HEAP->fixed_array_map());
1744 int offset = kHeaderSize + index * kDoubleSize;
1745 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1746 WRITE_DOUBLE_FIELD(this, offset, value);
1747}
1748
1749
1750void FixedDoubleArray::set_the_hole(int index) {
1751 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1752 map() != HEAP->fixed_array_map());
1753 int offset = kHeaderSize + index * kDoubleSize;
1754 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1755}
1756
1757
1758bool FixedDoubleArray::is_the_hole(int index) {
1759 int offset = kHeaderSize + index * kDoubleSize;
1760 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1761}
1762
1763
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001764WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001765 Heap* heap = GetHeap();
1766 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1767 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001768 return UPDATE_WRITE_BARRIER;
1769}
1770
1771
1772void FixedArray::set(int index,
1773 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001774 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001775 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001776 ASSERT(index >= 0 && index < this->length());
1777 int offset = kHeaderSize + index * kPointerSize;
1778 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001779 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001780}
1781
1782
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001783void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1784 int index,
1785 Object* value) {
1786 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
1787 ASSERT(index >= 0 && index < array->length());
1788 int offset = kHeaderSize + index * kPointerSize;
1789 WRITE_FIELD(array, offset, value);
1790 Heap* heap = array->GetHeap();
1791 if (heap->InNewSpace(value)) {
1792 heap->RecordWrite(array->address(), offset);
1793 }
1794}
1795
1796
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001797void FixedArray::NoWriteBarrierSet(FixedArray* array,
1798 int index,
1799 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001800 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001801 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001802 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001803 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1804}
1805
1806
1807void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001808 ASSERT(map() != HEAP->fixed_cow_array_map());
1809 set_undefined(GetHeap(), index);
1810}
1811
1812
1813void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001814 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001815 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001816 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001817 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001818}
1819
1820
ager@chromium.org236ad962008-09-25 09:45:57 +00001821void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001822 set_null(GetHeap(), index);
1823}
1824
1825
1826void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001827 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001828 ASSERT(!heap->InNewSpace(heap->null_value()));
1829 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001830}
1831
1832
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001833void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001834 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001835 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001836 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1837 WRITE_FIELD(this,
1838 kHeaderSize + index * kPointerSize,
1839 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001840}
1841
1842
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001843void FixedArray::set_unchecked(int index, Smi* value) {
1844 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1845 int offset = kHeaderSize + index * kPointerSize;
1846 WRITE_FIELD(this, offset, value);
1847}
1848
1849
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001850void FixedArray::set_unchecked(Heap* heap,
1851 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001852 Object* value,
1853 WriteBarrierMode mode) {
1854 int offset = kHeaderSize + index * kPointerSize;
1855 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001856 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001857}
1858
1859
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001860void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001861 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001862 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1863 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001864}
1865
1866
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001867Object** FixedArray::data_start() {
1868 return HeapObject::RawField(this, kHeaderSize);
1869}
1870
1871
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001872bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001873 ASSERT(this->IsSmi() ||
1874 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001875 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001876 return this->IsSmi() || length() <= kFirstIndex;
1877}
1878
1879
1880int DescriptorArray::bit_field3_storage() {
1881 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1882 return Smi::cast(storage)->value();
1883}
1884
1885void DescriptorArray::set_bit_field3_storage(int value) {
1886 ASSERT(!IsEmpty());
1887 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001888}
1889
1890
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001891void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1892 int first,
1893 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001894 Object* tmp = array->get(first);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001895 NoIncrementalWriteBarrierSet(array, first, array->get(second));
1896 NoIncrementalWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001897}
1898
1899
1900int DescriptorArray::Search(String* name) {
1901 SLOW_ASSERT(IsSortedNoDuplicates());
1902
1903 // Check for empty descriptor array.
1904 int nof = number_of_descriptors();
1905 if (nof == 0) return kNotFound;
1906
1907 // Fast case: do linear search for small arrays.
1908 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001909 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001910 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001911 }
1912
1913 // Slow case: perform binary search.
1914 return BinarySearch(name, 0, nof - 1);
1915}
1916
1917
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001918int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001919 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001920 if (number == DescriptorLookupCache::kAbsent) {
1921 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001922 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001923 }
1924 return number;
1925}
1926
1927
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001928String* DescriptorArray::GetKey(int descriptor_number) {
1929 ASSERT(descriptor_number < number_of_descriptors());
1930 return String::cast(get(ToKeyIndex(descriptor_number)));
1931}
1932
1933
1934Object* DescriptorArray::GetValue(int descriptor_number) {
1935 ASSERT(descriptor_number < number_of_descriptors());
1936 return GetContentArray()->get(ToValueIndex(descriptor_number));
1937}
1938
1939
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001940PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001941 ASSERT(descriptor_number < number_of_descriptors());
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001942 Object* details = GetContentArray()->get(ToDetailsIndex(descriptor_number));
1943 return PropertyDetails(Smi::cast(details));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001944}
1945
1946
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001947PropertyType DescriptorArray::GetType(int descriptor_number) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001948 return GetDetails(descriptor_number).type();
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001949}
1950
1951
1952int DescriptorArray::GetFieldIndex(int descriptor_number) {
1953 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1954}
1955
1956
1957JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1958 return JSFunction::cast(GetValue(descriptor_number));
1959}
1960
1961
1962Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1963 ASSERT(GetType(descriptor_number) == CALLBACKS);
1964 return GetValue(descriptor_number);
1965}
1966
1967
1968AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1969 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001970 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001971 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001972}
1973
1974
1975bool DescriptorArray::IsProperty(int descriptor_number) {
ulan@chromium.org9a21ec42012-03-06 08:42:24 +00001976 Entry entry(this, descriptor_number);
1977 return IsPropertyDescriptor(&entry);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001978}
1979
1980
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001981bool DescriptorArray::IsTransitionOnly(int descriptor_number) {
1982 switch (GetType(descriptor_number)) {
1983 case MAP_TRANSITION:
1984 case CONSTANT_TRANSITION:
1985 case ELEMENTS_TRANSITION:
1986 return true;
1987 case CALLBACKS: {
1988 Object* value = GetValue(descriptor_number);
1989 if (!value->IsAccessorPair()) return false;
1990 AccessorPair* accessors = AccessorPair::cast(value);
1991 return accessors->getter()->IsMap() && accessors->setter()->IsMap();
1992 }
1993 case NORMAL:
1994 case FIELD:
1995 case CONSTANT_FUNCTION:
1996 case HANDLER:
1997 case INTERCEPTOR:
1998 case NULL_DESCRIPTOR:
1999 return false;
2000 }
2001 UNREACHABLE(); // Keep the compiler happy.
2002 return false;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002003}
2004
2005
2006bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
2007 return GetType(descriptor_number) == NULL_DESCRIPTOR;
2008}
2009
2010
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002011void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2012 desc->Init(GetKey(descriptor_number),
2013 GetValue(descriptor_number),
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002014 GetDetails(descriptor_number));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002015}
2016
2017
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002018void DescriptorArray::Set(int descriptor_number,
2019 Descriptor* desc,
2020 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002021 // Range check.
2022 ASSERT(descriptor_number < number_of_descriptors());
2023
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002024 NoIncrementalWriteBarrierSet(this,
2025 ToKeyIndex(descriptor_number),
2026 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002027 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002028 NoIncrementalWriteBarrierSet(content_array,
2029 ToValueIndex(descriptor_number),
2030 desc->GetValue());
2031 NoIncrementalWriteBarrierSet(content_array,
2032 ToDetailsIndex(descriptor_number),
2033 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002034}
2035
2036
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002037void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2038 int first, int second) {
2039 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002040 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002041 NoIncrementalWriteBarrierSwap(content_array,
2042 ToValueIndex(first),
2043 ToValueIndex(second));
2044 NoIncrementalWriteBarrierSwap(content_array,
2045 ToDetailsIndex(first),
2046 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002047}
2048
2049
2050DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
2051 : marking_(array->GetHeap()->incremental_marking()) {
2052 marking_->EnterNoMarkingScope();
2053 if (array->number_of_descriptors() > 0) {
2054 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
2055 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
2056 }
2057}
2058
2059
2060DescriptorArray::WhitenessWitness::~WhitenessWitness() {
2061 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002062}
2063
2064
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002065template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002066int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2067 const int kMinCapacity = 32;
2068 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2069 if (capacity < kMinCapacity) {
2070 capacity = kMinCapacity; // Guarantee min capacity.
2071 }
2072 return capacity;
2073}
2074
2075
2076template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002077int HashTable<Shape, Key>::FindEntry(Key key) {
2078 return FindEntry(GetIsolate(), key);
2079}
2080
2081
2082// Find entry for key otherwise return kNotFound.
2083template<typename Shape, typename Key>
2084int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2085 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002086 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002087 uint32_t count = 1;
2088 // EnsureCapacity will guarantee the hash table is never full.
2089 while (true) {
2090 Object* element = KeyAt(entry);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002091 // Empty entry.
2092 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2093 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002094 Shape::IsMatch(key, element)) return entry;
2095 entry = NextProbe(entry, count++, capacity);
2096 }
2097 return kNotFound;
2098}
2099
2100
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002101bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002102 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002103 if (!max_index_object->IsSmi()) return false;
2104 return 0 !=
2105 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2106}
2107
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002108uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002109 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002110 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002111 if (!max_index_object->IsSmi()) return 0;
2112 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2113 return value >> kRequiresSlowElementsTagSize;
2114}
2115
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002116void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002117 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002118}
2119
2120
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002121// ------------------------------------
2122// Cast operations
2123
2124
2125CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002126CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002127CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002128CAST_ACCESSOR(DeoptimizationInputData)
2129CAST_ACCESSOR(DeoptimizationOutputData)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002130CAST_ACCESSOR(TypeFeedbackCells)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002131CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002132CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002133CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002134CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002135CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002136CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002137CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002138CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002139CAST_ACCESSOR(String)
2140CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002141CAST_ACCESSOR(SeqAsciiString)
2142CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002143CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002144CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002145CAST_ACCESSOR(ExternalString)
2146CAST_ACCESSOR(ExternalAsciiString)
2147CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002148CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002149CAST_ACCESSOR(JSObject)
2150CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002151CAST_ACCESSOR(HeapObject)
2152CAST_ACCESSOR(HeapNumber)
2153CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002154CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002155CAST_ACCESSOR(SharedFunctionInfo)
2156CAST_ACCESSOR(Map)
2157CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002158CAST_ACCESSOR(GlobalObject)
2159CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002160CAST_ACCESSOR(JSGlobalObject)
2161CAST_ACCESSOR(JSBuiltinsObject)
2162CAST_ACCESSOR(Code)
2163CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002164CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002165CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002166CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002167CAST_ACCESSOR(JSSet)
2168CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002169CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002170CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002171CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002172CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002173CAST_ACCESSOR(ExternalArray)
2174CAST_ACCESSOR(ExternalByteArray)
2175CAST_ACCESSOR(ExternalUnsignedByteArray)
2176CAST_ACCESSOR(ExternalShortArray)
2177CAST_ACCESSOR(ExternalUnsignedShortArray)
2178CAST_ACCESSOR(ExternalIntArray)
2179CAST_ACCESSOR(ExternalUnsignedIntArray)
2180CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002181CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002182CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002183CAST_ACCESSOR(Struct)
2184
2185
2186#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2187 STRUCT_LIST(MAKE_STRUCT_CAST)
2188#undef MAKE_STRUCT_CAST
2189
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002190
2191template <typename Shape, typename Key>
2192HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002193 ASSERT(obj->IsHashTable());
2194 return reinterpret_cast<HashTable*>(obj);
2195}
2196
2197
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002198SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002199SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002200
ager@chromium.orgac091b72010-05-05 07:34:42 +00002201SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002202
2203
2204uint32_t String::hash_field() {
2205 return READ_UINT32_FIELD(this, kHashFieldOffset);
2206}
2207
2208
2209void String::set_hash_field(uint32_t value) {
2210 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002211#if V8_HOST_ARCH_64_BIT
2212 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2213#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002214}
2215
2216
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002217bool String::Equals(String* other) {
2218 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002219 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2220 return false;
2221 }
2222 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002223}
2224
2225
lrn@chromium.org303ada72010-10-27 09:33:13 +00002226MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002227 if (!StringShape(this).IsCons()) return this;
2228 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002229 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002230 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002231}
2232
2233
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002234String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002235 MaybeObject* flat = TryFlatten(pretenure);
2236 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002237 if (!flat->ToObject(&successfully_flattened)) return this;
2238 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002239}
2240
2241
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002242uint16_t String::Get(int index) {
2243 ASSERT(index >= 0 && index < length());
2244 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002245 case kSeqStringTag | kAsciiStringTag:
2246 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2247 case kSeqStringTag | kTwoByteStringTag:
2248 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2249 case kConsStringTag | kAsciiStringTag:
2250 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002251 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002252 case kExternalStringTag | kAsciiStringTag:
2253 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2254 case kExternalStringTag | kTwoByteStringTag:
2255 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002256 case kSlicedStringTag | kAsciiStringTag:
2257 case kSlicedStringTag | kTwoByteStringTag:
2258 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002259 default:
2260 break;
2261 }
2262
2263 UNREACHABLE();
2264 return 0;
2265}
2266
2267
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002268void String::Set(int index, uint16_t value) {
2269 ASSERT(index >= 0 && index < length());
2270 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002271
ager@chromium.org5ec48922009-05-05 07:25:34 +00002272 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002273 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2274 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002275}
2276
2277
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002278bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002279 if (!StringShape(this).IsCons()) return true;
2280 return ConsString::cast(this)->second()->length() == 0;
2281}
2282
2283
2284String* String::GetUnderlying() {
2285 // Giving direct access to underlying string only makes sense if the
2286 // wrapping string is already flattened.
2287 ASSERT(this->IsFlat());
2288 ASSERT(StringShape(this).IsIndirect());
2289 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2290 const int kUnderlyingOffset = SlicedString::kParentOffset;
2291 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002292}
2293
2294
ager@chromium.org7c537e22008-10-16 08:43:32 +00002295uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002296 ASSERT(index >= 0 && index < length());
2297 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2298}
2299
2300
ager@chromium.org7c537e22008-10-16 08:43:32 +00002301void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002302 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2303 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2304 static_cast<byte>(value));
2305}
2306
2307
ager@chromium.org7c537e22008-10-16 08:43:32 +00002308Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002309 return FIELD_ADDR(this, kHeaderSize);
2310}
2311
2312
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002313char* SeqAsciiString::GetChars() {
2314 return reinterpret_cast<char*>(GetCharsAddress());
2315}
2316
2317
ager@chromium.org7c537e22008-10-16 08:43:32 +00002318Address SeqTwoByteString::GetCharsAddress() {
2319 return FIELD_ADDR(this, kHeaderSize);
2320}
2321
2322
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002323uc16* SeqTwoByteString::GetChars() {
2324 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2325}
2326
2327
ager@chromium.org7c537e22008-10-16 08:43:32 +00002328uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002329 ASSERT(index >= 0 && index < length());
2330 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2331}
2332
2333
ager@chromium.org7c537e22008-10-16 08:43:32 +00002334void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002335 ASSERT(index >= 0 && index < length());
2336 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2337}
2338
2339
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002340int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002341 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002342}
2343
2344
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002345int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002346 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002347}
2348
2349
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002350String* SlicedString::parent() {
2351 return String::cast(READ_FIELD(this, kParentOffset));
2352}
2353
2354
2355void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002356 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002357 WRITE_FIELD(this, kParentOffset, parent);
2358}
2359
2360
2361SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2362
2363
ager@chromium.org870a0b62008-11-04 11:43:05 +00002364String* ConsString::first() {
2365 return String::cast(READ_FIELD(this, kFirstOffset));
2366}
2367
2368
2369Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002370 return READ_FIELD(this, kFirstOffset);
2371}
2372
2373
ager@chromium.org870a0b62008-11-04 11:43:05 +00002374void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002375 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002376 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002377}
2378
2379
ager@chromium.org870a0b62008-11-04 11:43:05 +00002380String* ConsString::second() {
2381 return String::cast(READ_FIELD(this, kSecondOffset));
2382}
2383
2384
2385Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002386 return READ_FIELD(this, kSecondOffset);
2387}
2388
2389
ager@chromium.org870a0b62008-11-04 11:43:05 +00002390void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002391 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002392 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002393}
2394
2395
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002396bool ExternalString::is_short() {
2397 InstanceType type = map()->instance_type();
2398 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002399}
2400
2401
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002402const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002403 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2404}
2405
2406
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002407void ExternalAsciiString::update_data_cache() {
2408 if (is_short()) return;
2409 const char** data_field =
2410 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2411 *data_field = resource()->data();
2412}
2413
2414
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002415void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002416 const ExternalAsciiString::Resource* resource) {
2417 *reinterpret_cast<const Resource**>(
2418 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002419 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002420}
2421
2422
2423const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002424 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002425}
2426
2427
2428uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2429 ASSERT(index >= 0 && index < length());
2430 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002431}
2432
2433
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002434const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002435 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2436}
2437
2438
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002439void ExternalTwoByteString::update_data_cache() {
2440 if (is_short()) return;
2441 const uint16_t** data_field =
2442 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2443 *data_field = resource()->data();
2444}
2445
2446
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002447void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002448 const ExternalTwoByteString::Resource* resource) {
2449 *reinterpret_cast<const Resource**>(
2450 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002451 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002452}
2453
2454
2455const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002456 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002457}
2458
2459
2460uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2461 ASSERT(index >= 0 && index < length());
2462 return GetChars()[index];
2463}
2464
2465
2466const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2467 unsigned start) {
2468 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002469}
2470
2471
ager@chromium.orgac091b72010-05-05 07:34:42 +00002472void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002473 set_finger_index(kEntriesIndex);
2474 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002475}
2476
2477
2478void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002479 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002480 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002481 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002482 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002483 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002484 MakeZeroSize();
2485}
2486
2487
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002488int JSFunctionResultCache::size() {
2489 return Smi::cast(get(kCacheSizeIndex))->value();
2490}
2491
2492
2493void JSFunctionResultCache::set_size(int size) {
2494 set(kCacheSizeIndex, Smi::FromInt(size));
2495}
2496
2497
2498int JSFunctionResultCache::finger_index() {
2499 return Smi::cast(get(kFingerIndex))->value();
2500}
2501
2502
2503void JSFunctionResultCache::set_finger_index(int finger_index) {
2504 set(kFingerIndex, Smi::FromInt(finger_index));
2505}
2506
2507
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002508byte ByteArray::get(int index) {
2509 ASSERT(index >= 0 && index < this->length());
2510 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2511}
2512
2513
2514void ByteArray::set(int index, byte value) {
2515 ASSERT(index >= 0 && index < this->length());
2516 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2517}
2518
2519
2520int ByteArray::get_int(int index) {
2521 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2522 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2523}
2524
2525
2526ByteArray* ByteArray::FromDataStartAddress(Address address) {
2527 ASSERT_TAG_ALIGNED(address);
2528 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2529}
2530
2531
2532Address ByteArray::GetDataStartAddress() {
2533 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2534}
2535
2536
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002537uint8_t* ExternalPixelArray::external_pixel_pointer() {
2538 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002539}
2540
2541
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002542uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002543 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002544 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002545 return ptr[index];
2546}
2547
2548
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002549MaybeObject* ExternalPixelArray::get(int index) {
2550 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2551}
2552
2553
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002554void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002555 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002556 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002557 ptr[index] = value;
2558}
2559
2560
ager@chromium.org3811b432009-10-28 14:53:37 +00002561void* ExternalArray::external_pointer() {
2562 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2563 return reinterpret_cast<void*>(ptr);
2564}
2565
2566
2567void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2568 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2569 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2570}
2571
2572
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002573int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002574 ASSERT((index >= 0) && (index < this->length()));
2575 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2576 return ptr[index];
2577}
2578
2579
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002580MaybeObject* ExternalByteArray::get(int index) {
2581 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2582}
2583
2584
ager@chromium.org3811b432009-10-28 14:53:37 +00002585void ExternalByteArray::set(int index, int8_t value) {
2586 ASSERT((index >= 0) && (index < this->length()));
2587 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2588 ptr[index] = value;
2589}
2590
2591
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002592uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002593 ASSERT((index >= 0) && (index < this->length()));
2594 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2595 return ptr[index];
2596}
2597
2598
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002599MaybeObject* ExternalUnsignedByteArray::get(int index) {
2600 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2601}
2602
2603
ager@chromium.org3811b432009-10-28 14:53:37 +00002604void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2605 ASSERT((index >= 0) && (index < this->length()));
2606 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2607 ptr[index] = value;
2608}
2609
2610
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002611int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002612 ASSERT((index >= 0) && (index < this->length()));
2613 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2614 return ptr[index];
2615}
2616
2617
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002618MaybeObject* ExternalShortArray::get(int index) {
2619 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2620}
2621
2622
ager@chromium.org3811b432009-10-28 14:53:37 +00002623void ExternalShortArray::set(int index, int16_t value) {
2624 ASSERT((index >= 0) && (index < this->length()));
2625 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2626 ptr[index] = value;
2627}
2628
2629
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002630uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002631 ASSERT((index >= 0) && (index < this->length()));
2632 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2633 return ptr[index];
2634}
2635
2636
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002637MaybeObject* ExternalUnsignedShortArray::get(int index) {
2638 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2639}
2640
2641
ager@chromium.org3811b432009-10-28 14:53:37 +00002642void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2643 ASSERT((index >= 0) && (index < this->length()));
2644 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2645 ptr[index] = value;
2646}
2647
2648
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002649int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002650 ASSERT((index >= 0) && (index < this->length()));
2651 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2652 return ptr[index];
2653}
2654
2655
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002656MaybeObject* ExternalIntArray::get(int index) {
2657 return GetHeap()->NumberFromInt32(get_scalar(index));
2658}
2659
2660
ager@chromium.org3811b432009-10-28 14:53:37 +00002661void ExternalIntArray::set(int index, int32_t value) {
2662 ASSERT((index >= 0) && (index < this->length()));
2663 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2664 ptr[index] = value;
2665}
2666
2667
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002668uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002669 ASSERT((index >= 0) && (index < this->length()));
2670 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2671 return ptr[index];
2672}
2673
2674
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002675MaybeObject* ExternalUnsignedIntArray::get(int index) {
2676 return GetHeap()->NumberFromUint32(get_scalar(index));
2677}
2678
2679
ager@chromium.org3811b432009-10-28 14:53:37 +00002680void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2681 ASSERT((index >= 0) && (index < this->length()));
2682 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2683 ptr[index] = value;
2684}
2685
2686
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002687float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002688 ASSERT((index >= 0) && (index < this->length()));
2689 float* ptr = static_cast<float*>(external_pointer());
2690 return ptr[index];
2691}
2692
2693
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002694MaybeObject* ExternalFloatArray::get(int index) {
2695 return GetHeap()->NumberFromDouble(get_scalar(index));
2696}
2697
2698
ager@chromium.org3811b432009-10-28 14:53:37 +00002699void ExternalFloatArray::set(int index, float value) {
2700 ASSERT((index >= 0) && (index < this->length()));
2701 float* ptr = static_cast<float*>(external_pointer());
2702 ptr[index] = value;
2703}
2704
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002705
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002706double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002707 ASSERT((index >= 0) && (index < this->length()));
2708 double* ptr = static_cast<double*>(external_pointer());
2709 return ptr[index];
2710}
2711
2712
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002713MaybeObject* ExternalDoubleArray::get(int index) {
2714 return GetHeap()->NumberFromDouble(get_scalar(index));
2715}
2716
2717
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002718void ExternalDoubleArray::set(int index, double value) {
2719 ASSERT((index >= 0) && (index < this->length()));
2720 double* ptr = static_cast<double*>(external_pointer());
2721 ptr[index] = value;
2722}
2723
2724
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002725int Map::visitor_id() {
2726 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2727}
2728
2729
2730void Map::set_visitor_id(int id) {
2731 ASSERT(0 <= id && id < 256);
2732 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2733}
2734
ager@chromium.org3811b432009-10-28 14:53:37 +00002735
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002736int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002737 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2738}
2739
2740
2741int Map::inobject_properties() {
2742 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002743}
2744
2745
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002746int Map::pre_allocated_property_fields() {
2747 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2748}
2749
2750
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002751int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002752 int instance_size = map->instance_size();
2753 if (instance_size != kVariableSizeSentinel) return instance_size;
2754 // We can ignore the "symbol" bit becase it is only set for symbols
2755 // and implies a string type.
2756 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002757 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002758 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002759 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002760 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002761 if (instance_type == ASCII_STRING_TYPE) {
2762 return SeqAsciiString::SizeFor(
2763 reinterpret_cast<SeqAsciiString*>(this)->length());
2764 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002765 if (instance_type == BYTE_ARRAY_TYPE) {
2766 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2767 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002768 if (instance_type == FREE_SPACE_TYPE) {
2769 return reinterpret_cast<FreeSpace*>(this)->size();
2770 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002771 if (instance_type == STRING_TYPE) {
2772 return SeqTwoByteString::SizeFor(
2773 reinterpret_cast<SeqTwoByteString*>(this)->length());
2774 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002775 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2776 return FixedDoubleArray::SizeFor(
2777 reinterpret_cast<FixedDoubleArray*>(this)->length());
2778 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002779 ASSERT(instance_type == CODE_TYPE);
2780 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002781}
2782
2783
2784void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002785 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002786 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002787 ASSERT(0 <= value && value < 256);
2788 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2789}
2790
2791
ager@chromium.org7c537e22008-10-16 08:43:32 +00002792void Map::set_inobject_properties(int value) {
2793 ASSERT(0 <= value && value < 256);
2794 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2795}
2796
2797
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002798void Map::set_pre_allocated_property_fields(int value) {
2799 ASSERT(0 <= value && value < 256);
2800 WRITE_BYTE_FIELD(this,
2801 kPreAllocatedPropertyFieldsOffset,
2802 static_cast<byte>(value));
2803}
2804
2805
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002806InstanceType Map::instance_type() {
2807 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2808}
2809
2810
2811void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002812 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2813}
2814
2815
2816int Map::unused_property_fields() {
2817 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2818}
2819
2820
2821void Map::set_unused_property_fields(int value) {
2822 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2823}
2824
2825
2826byte Map::bit_field() {
2827 return READ_BYTE_FIELD(this, kBitFieldOffset);
2828}
2829
2830
2831void Map::set_bit_field(byte value) {
2832 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2833}
2834
2835
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002836byte Map::bit_field2() {
2837 return READ_BYTE_FIELD(this, kBitField2Offset);
2838}
2839
2840
2841void Map::set_bit_field2(byte value) {
2842 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2843}
2844
2845
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002846void Map::set_non_instance_prototype(bool value) {
2847 if (value) {
2848 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2849 } else {
2850 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2851 }
2852}
2853
2854
2855bool Map::has_non_instance_prototype() {
2856 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2857}
2858
2859
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002860void Map::set_function_with_prototype(bool value) {
2861 if (value) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002862 set_bit_field3(bit_field3() | (1 << kFunctionWithPrototype));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002863 } else {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002864 set_bit_field3(bit_field3() & ~(1 << kFunctionWithPrototype));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002865 }
2866}
2867
2868
2869bool Map::function_with_prototype() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002870 return ((1 << kFunctionWithPrototype) & bit_field3()) != 0;
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002871}
2872
2873
ager@chromium.org870a0b62008-11-04 11:43:05 +00002874void Map::set_is_access_check_needed(bool access_check_needed) {
2875 if (access_check_needed) {
2876 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2877 } else {
2878 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2879 }
2880}
2881
2882
2883bool Map::is_access_check_needed() {
2884 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2885}
2886
2887
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002888void Map::set_is_extensible(bool value) {
2889 if (value) {
2890 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2891 } else {
2892 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2893 }
2894}
2895
2896bool Map::is_extensible() {
2897 return ((1 << kIsExtensible) & bit_field2()) != 0;
2898}
2899
2900
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002901void Map::set_attached_to_shared_function_info(bool value) {
2902 if (value) {
2903 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2904 } else {
2905 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2906 }
2907}
2908
2909bool Map::attached_to_shared_function_info() {
2910 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2911}
2912
2913
2914void Map::set_is_shared(bool value) {
2915 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002916 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002917 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002918 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002919 }
2920}
2921
2922bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002923 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002924}
2925
2926
2927JSFunction* Map::unchecked_constructor() {
2928 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2929}
2930
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002931
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002932Code::Flags Code::flags() {
2933 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2934}
2935
2936
2937void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002938 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002939 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002940 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2941 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002942 ExtractArgumentsCountFromFlags(flags) >= 0);
2943 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2944}
2945
2946
2947Code::Kind Code::kind() {
2948 return ExtractKindFromFlags(flags());
2949}
2950
2951
kasper.lund7276f142008-07-30 08:49:36 +00002952InlineCacheState Code::ic_state() {
2953 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002954 // Only allow uninitialized or debugger states for non-IC code
2955 // objects. This is used in the debugger to determine whether or not
2956 // a call to code object has been replaced with a debug break call.
2957 ASSERT(is_inline_cache_stub() ||
2958 result == UNINITIALIZED ||
2959 result == DEBUG_BREAK ||
2960 result == DEBUG_PREPARE_STEP_IN);
2961 return result;
2962}
2963
2964
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002965Code::ExtraICState Code::extra_ic_state() {
2966 ASSERT(is_inline_cache_stub());
2967 return ExtractExtraICStateFromFlags(flags());
2968}
2969
2970
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002971PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002972 return ExtractTypeFromFlags(flags());
2973}
2974
2975
2976int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002977 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002978 return ExtractArgumentsCountFromFlags(flags());
2979}
2980
2981
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002982int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002983 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002984 kind() == UNARY_OP_IC ||
2985 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002986 kind() == COMPARE_IC ||
2987 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002988 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002989}
2990
2991
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002992void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002993 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002994 kind() == UNARY_OP_IC ||
2995 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002996 kind() == COMPARE_IC ||
2997 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002998 ASSERT(0 <= major && major < 256);
2999 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003000}
3001
3002
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003003bool Code::is_pregenerated() {
3004 return kind() == STUB && IsPregeneratedField::decode(flags());
3005}
3006
3007
3008void Code::set_is_pregenerated(bool value) {
3009 ASSERT(kind() == STUB);
3010 Flags f = flags();
3011 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3012 set_flags(f);
3013}
3014
3015
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003016bool Code::optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003017 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003018 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3019}
3020
3021
3022void Code::set_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003023 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003024 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3025}
3026
3027
3028bool Code::has_deoptimization_support() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003029 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003030 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3031 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003032}
3033
3034
3035void Code::set_has_deoptimization_support(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003036 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003037 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3038 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3039 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3040}
3041
3042
3043bool Code::has_debug_break_slots() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003044 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003045 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3046 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3047}
3048
3049
3050void Code::set_has_debug_break_slots(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003051 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003052 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3053 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3054 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003055}
3056
3057
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003058bool Code::is_compiled_optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003059 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003060 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3061 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3062}
3063
3064
3065void Code::set_compiled_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003066 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003067 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3068 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3069 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3070}
3071
3072
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003073int Code::allow_osr_at_loop_nesting_level() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003074 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003075 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3076}
3077
3078
3079void Code::set_allow_osr_at_loop_nesting_level(int level) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003080 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003081 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3082 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3083}
3084
3085
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003086int Code::profiler_ticks() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003087 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003088 return READ_BYTE_FIELD(this, kProfilerTicksOffset);
3089}
3090
3091
3092void Code::set_profiler_ticks(int ticks) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003093 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003094 ASSERT(ticks < 256);
3095 WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
3096}
3097
3098
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003099unsigned Code::stack_slots() {
3100 ASSERT(kind() == OPTIMIZED_FUNCTION);
3101 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3102}
3103
3104
3105void Code::set_stack_slots(unsigned slots) {
3106 ASSERT(kind() == OPTIMIZED_FUNCTION);
3107 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3108}
3109
3110
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003111unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003112 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003113 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003114}
3115
3116
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003117void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003118 ASSERT(kind() == OPTIMIZED_FUNCTION);
3119 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003120 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003121}
3122
3123
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003124unsigned Code::stack_check_table_offset() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003125 ASSERT_EQ(FUNCTION, kind());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003126 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003127}
3128
3129
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003130void Code::set_stack_check_table_offset(unsigned offset) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003131 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003132 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003133 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003134}
3135
3136
3137CheckType Code::check_type() {
3138 ASSERT(is_call_stub() || is_keyed_call_stub());
3139 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3140 return static_cast<CheckType>(type);
3141}
3142
3143
3144void Code::set_check_type(CheckType value) {
3145 ASSERT(is_call_stub() || is_keyed_call_stub());
3146 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3147}
3148
3149
danno@chromium.org40cb8782011-05-25 07:58:50 +00003150byte Code::unary_op_type() {
3151 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003152 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3153}
3154
3155
danno@chromium.org40cb8782011-05-25 07:58:50 +00003156void Code::set_unary_op_type(byte value) {
3157 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003158 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3159}
3160
3161
danno@chromium.org40cb8782011-05-25 07:58:50 +00003162byte Code::binary_op_type() {
3163 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003164 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3165}
3166
3167
danno@chromium.org40cb8782011-05-25 07:58:50 +00003168void Code::set_binary_op_type(byte value) {
3169 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003170 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3171}
3172
3173
danno@chromium.org40cb8782011-05-25 07:58:50 +00003174byte Code::binary_op_result_type() {
3175 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003176 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3177}
3178
3179
danno@chromium.org40cb8782011-05-25 07:58:50 +00003180void Code::set_binary_op_result_type(byte value) {
3181 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003182 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3183}
3184
3185
3186byte Code::compare_state() {
3187 ASSERT(is_compare_ic_stub());
3188 return READ_BYTE_FIELD(this, kCompareStateOffset);
3189}
3190
3191
3192void Code::set_compare_state(byte value) {
3193 ASSERT(is_compare_ic_stub());
3194 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3195}
3196
3197
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003198byte Code::compare_operation() {
3199 ASSERT(is_compare_ic_stub());
3200 return READ_BYTE_FIELD(this, kCompareOperationOffset);
3201}
3202
3203
3204void Code::set_compare_operation(byte value) {
3205 ASSERT(is_compare_ic_stub());
3206 WRITE_BYTE_FIELD(this, kCompareOperationOffset, value);
3207}
3208
3209
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003210byte Code::to_boolean_state() {
3211 ASSERT(is_to_boolean_ic_stub());
3212 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3213}
3214
3215
3216void Code::set_to_boolean_state(byte value) {
3217 ASSERT(is_to_boolean_ic_stub());
3218 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3219}
3220
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003221
3222bool Code::has_function_cache() {
3223 ASSERT(kind() == STUB);
3224 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3225}
3226
3227
3228void Code::set_has_function_cache(bool flag) {
3229 ASSERT(kind() == STUB);
3230 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3231}
3232
3233
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003234bool Code::is_inline_cache_stub() {
3235 Kind kind = this->kind();
3236 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3237}
3238
3239
3240Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003241 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003242 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003243 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003244 int argc,
3245 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003246 // Extra IC state is only allowed for call IC stubs or for store IC
3247 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003248 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003249 kind == CALL_IC ||
3250 kind == STORE_IC ||
3251 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003252 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003253 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003254 | ICStateField::encode(ic_state)
3255 | TypeField::encode(type)
3256 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003257 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003258 | CacheHolderField::encode(holder);
3259 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003260}
3261
3262
3263Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3264 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003265 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003266 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003267 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003268 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003269}
3270
3271
3272Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003273 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003274}
3275
3276
kasper.lund7276f142008-07-30 08:49:36 +00003277InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003278 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003279}
3280
3281
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003282Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003283 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003284}
3285
3286
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003287PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003288 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003289}
3290
3291
3292int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003293 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003294}
3295
3296
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003297InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003298 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003299}
3300
3301
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003302Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003303 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003304 return static_cast<Flags>(bits);
3305}
3306
3307
ager@chromium.org8bb60582008-12-11 12:02:20 +00003308Code* Code::GetCodeFromTargetAddress(Address address) {
3309 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3310 // GetCodeFromTargetAddress might be called when marking objects during mark
3311 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3312 // Code::cast. Code::cast does not work when the object's map is
3313 // marked.
3314 Code* result = reinterpret_cast<Code*>(code);
3315 return result;
3316}
3317
3318
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003319Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3320 return HeapObject::
3321 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3322}
3323
3324
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003325Object* Map::prototype() {
3326 return READ_FIELD(this, kPrototypeOffset);
3327}
3328
3329
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003330void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003331 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003332 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003333 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003334}
3335
3336
danno@chromium.org40cb8782011-05-25 07:58:50 +00003337DescriptorArray* Map::instance_descriptors() {
3338 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3339 if (object->IsSmi()) {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003340 return GetHeap()->empty_descriptor_array();
danno@chromium.org40cb8782011-05-25 07:58:50 +00003341 } else {
3342 return DescriptorArray::cast(object);
3343 }
3344}
3345
3346
3347void Map::init_instance_descriptors() {
3348 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3349}
3350
3351
3352void Map::clear_instance_descriptors() {
3353 Object* object = READ_FIELD(this,
3354 kInstanceDescriptorsOrBitField3Offset);
3355 if (!object->IsSmi()) {
yangguo@chromium.org5f0b8ea2012-05-16 12:37:04 +00003356#ifdef DEBUG
3357 ZapInstanceDescriptors();
3358#endif
danno@chromium.org40cb8782011-05-25 07:58:50 +00003359 WRITE_FIELD(
3360 this,
3361 kInstanceDescriptorsOrBitField3Offset,
3362 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3363 }
3364}
3365
3366
3367void Map::set_instance_descriptors(DescriptorArray* value,
3368 WriteBarrierMode mode) {
3369 Object* object = READ_FIELD(this,
3370 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003371 Heap* heap = GetHeap();
3372 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003373 clear_instance_descriptors();
3374 return;
3375 } else {
3376 if (object->IsSmi()) {
3377 value->set_bit_field3_storage(Smi::cast(object)->value());
3378 } else {
3379 value->set_bit_field3_storage(
3380 DescriptorArray::cast(object)->bit_field3_storage());
3381 }
3382 }
3383 ASSERT(!is_shared());
yangguo@chromium.org5f0b8ea2012-05-16 12:37:04 +00003384#ifdef DEBUG
3385 if (value != instance_descriptors()) {
3386 ZapInstanceDescriptors();
3387 }
3388#endif
danno@chromium.org40cb8782011-05-25 07:58:50 +00003389 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003390 CONDITIONAL_WRITE_BARRIER(
3391 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003392}
3393
3394
3395int Map::bit_field3() {
3396 Object* object = READ_FIELD(this,
3397 kInstanceDescriptorsOrBitField3Offset);
3398 if (object->IsSmi()) {
3399 return Smi::cast(object)->value();
3400 } else {
3401 return DescriptorArray::cast(object)->bit_field3_storage();
3402 }
3403}
3404
3405
3406void Map::set_bit_field3(int value) {
3407 ASSERT(Smi::IsValid(value));
3408 Object* object = READ_FIELD(this,
3409 kInstanceDescriptorsOrBitField3Offset);
3410 if (object->IsSmi()) {
3411 WRITE_FIELD(this,
3412 kInstanceDescriptorsOrBitField3Offset,
3413 Smi::FromInt(value));
3414 } else {
3415 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3416 }
3417}
3418
3419
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003420Object* Map::GetBackPointer() {
3421 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3422 if (object->IsFixedArray()) {
3423 return FixedArray::cast(object)->get(kProtoTransitionBackPointerOffset);
3424 } else {
3425 return object;
3426 }
3427}
3428
3429
3430void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
3431 Heap* heap = GetHeap();
3432 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
3433 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
3434 (value->IsMap() && GetBackPointer()->IsUndefined()));
3435 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3436 if (object->IsFixedArray()) {
3437 FixedArray::cast(object)->set(
3438 kProtoTransitionBackPointerOffset, value, mode);
3439 } else {
3440 WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
3441 CONDITIONAL_WRITE_BARRIER(
3442 heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
3443 }
3444}
3445
3446
3447FixedArray* Map::prototype_transitions() {
3448 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3449 if (object->IsFixedArray()) {
3450 return FixedArray::cast(object);
3451 } else {
3452 return GetHeap()->empty_fixed_array();
3453 }
3454}
3455
3456
3457void Map::set_prototype_transitions(FixedArray* value, WriteBarrierMode mode) {
3458 Heap* heap = GetHeap();
3459 ASSERT(value != heap->empty_fixed_array());
3460 value->set(kProtoTransitionBackPointerOffset, GetBackPointer());
yangguo@chromium.org5f0b8ea2012-05-16 12:37:04 +00003461#ifdef DEBUG
3462 if (value != prototype_transitions()) {
3463 ZapPrototypeTransitions();
3464 }
3465#endif
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003466 WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
3467 CONDITIONAL_WRITE_BARRIER(
3468 heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
3469}
3470
3471
3472void Map::init_prototype_transitions(Object* undefined) {
3473 ASSERT(undefined->IsUndefined());
3474 WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, undefined);
3475}
3476
3477
3478HeapObject* Map::unchecked_prototype_transitions() {
3479 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3480 return reinterpret_cast<HeapObject*>(object);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003481}
3482
3483
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003484ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003485ACCESSORS(Map, constructor, Object, kConstructorOffset)
3486
3487ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003488ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003489ACCESSORS(JSFunction,
3490 next_function_link,
3491 Object,
3492 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003493
3494ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3495ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003496ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003497
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003498ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003499
3500ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3501ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3502ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3503ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003504ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003505
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003506ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3507ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3508
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003509ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3510ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3511ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3512
3513ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3514ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3515ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3516ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3517ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3518ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3519
3520ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3521ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3522
3523ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3524ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3525
3526ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3527ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003528ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3529 kPropertyAccessorsOffset)
3530ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3531 kPrototypeTemplateOffset)
3532ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3533ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3534 kNamedPropertyHandlerOffset)
3535ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3536 kIndexedPropertyHandlerOffset)
3537ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3538 kInstanceTemplateOffset)
3539ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3540ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003541ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3542 kInstanceCallHandlerOffset)
3543ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3544 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003545ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003546
3547ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003548ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3549 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003550
3551ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3552ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3553
3554ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3555
3556ACCESSORS(Script, source, Object, kSourceOffset)
3557ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003558ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003559ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
3560ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003561ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003562ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003563ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003564ACCESSORS_TO_SMI(Script, type, kTypeOffset)
3565ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
3566ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003567ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003568ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003569ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
3570 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003571
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003572#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003573ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3574ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3575ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3576ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3577
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003578ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
3579ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
3580ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003581ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003582#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003583
3584ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003585ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3586ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003587ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3588 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003589ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003590ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3591ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003592ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003593ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3594 kThisPropertyAssignmentsOffset)
danno@chromium.org1044a4d2012-04-30 12:34:39 +00003595SMI_ACCESSORS(SharedFunctionInfo, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003596
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00003597
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003598BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3599 kHiddenPrototypeBit)
3600BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3601BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3602 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003603BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3604 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003605BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3606 kIsExpressionBit)
3607BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3608 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003609BOOL_GETTER(SharedFunctionInfo,
3610 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003611 has_only_simple_this_property_assignments,
3612 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003613BOOL_ACCESSORS(SharedFunctionInfo,
3614 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003615 allows_lazy_compilation,
3616 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003617BOOL_ACCESSORS(SharedFunctionInfo,
3618 compiler_hints,
3619 uses_arguments,
3620 kUsesArguments)
3621BOOL_ACCESSORS(SharedFunctionInfo,
3622 compiler_hints,
3623 has_duplicate_parameters,
3624 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003625
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003626
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003627#if V8_HOST_ARCH_32_BIT
3628SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3629SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003630 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003631SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003632 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003633SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3634SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003635 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003636SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3637SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003638 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003639SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003640 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003641SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003642 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003643SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003644SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3645SMI_ACCESSORS(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003646#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003647
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003648#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003649 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003650 int holder::name() { \
3651 int value = READ_INT_FIELD(this, offset); \
3652 ASSERT(kHeapObjectTag == 1); \
3653 ASSERT((value & kHeapObjectTag) == 0); \
3654 return value >> 1; \
3655 } \
3656 void holder::set_##name(int value) { \
3657 ASSERT(kHeapObjectTag == 1); \
3658 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3659 (value & 0xC0000000) == 0x000000000); \
3660 WRITE_INT_FIELD(this, \
3661 offset, \
3662 (value << 1) & ~kHeapObjectTag); \
3663 }
3664
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003665#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3666 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003667 INT_ACCESSORS(holder, name, offset)
3668
3669
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003670PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003671PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3672 formal_parameter_count,
3673 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003674
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003675PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3676 expected_nof_properties,
3677 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003678PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3679
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003680PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3681PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3682 start_position_and_type,
3683 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003684
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003685PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3686 function_token_position,
3687 kFunctionTokenPositionOffset)
3688PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3689 compiler_hints,
3690 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003691
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003692PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3693 this_property_assignments_count,
3694 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003695PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003696
3697PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3698PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003699#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003700
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003701
3702int SharedFunctionInfo::construction_count() {
3703 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3704}
3705
3706
3707void SharedFunctionInfo::set_construction_count(int value) {
3708 ASSERT(0 <= value && value < 256);
3709 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3710}
3711
3712
whesse@chromium.org7b260152011-06-20 15:33:18 +00003713BOOL_ACCESSORS(SharedFunctionInfo,
3714 compiler_hints,
3715 live_objects_may_exist,
3716 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003717
3718
3719bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003720 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003721}
3722
3723
whesse@chromium.org7b260152011-06-20 15:33:18 +00003724BOOL_GETTER(SharedFunctionInfo,
3725 compiler_hints,
3726 optimization_disabled,
3727 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003728
3729
3730void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3731 set_compiler_hints(BooleanBit::set(compiler_hints(),
3732 kOptimizationDisabled,
3733 disable));
3734 // If disabling optimizations we reflect that in the code object so
3735 // it will not be counted as optimizable code.
3736 if ((code()->kind() == Code::FUNCTION) && disable) {
3737 code()->set_optimizable(false);
3738 }
3739}
3740
3741
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003742int SharedFunctionInfo::profiler_ticks() {
3743 if (code()->kind() != Code::FUNCTION) return 0;
3744 return code()->profiler_ticks();
3745}
3746
3747
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003748LanguageMode SharedFunctionInfo::language_mode() {
3749 int hints = compiler_hints();
3750 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3751 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3752 return EXTENDED_MODE;
3753 }
3754 return BooleanBit::get(hints, kStrictModeFunction)
3755 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003756}
3757
3758
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003759void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3760 // We only allow language mode transitions that go set the same language mode
3761 // again or go up in the chain:
3762 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3763 ASSERT(this->language_mode() == CLASSIC_MODE ||
3764 this->language_mode() == language_mode ||
3765 language_mode == EXTENDED_MODE);
3766 int hints = compiler_hints();
3767 hints = BooleanBit::set(
3768 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3769 hints = BooleanBit::set(
3770 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3771 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003772}
3773
3774
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003775bool SharedFunctionInfo::is_classic_mode() {
3776 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3777}
3778
3779BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3780 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003781BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3782BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3783 name_should_print_as_anonymous,
3784 kNameShouldPrintAsAnonymous)
3785BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3786BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00003787BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
3788BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
3789 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003790BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003791
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003792ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3793ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3794
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003795ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3796
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003797bool Script::HasValidSource() {
3798 Object* src = this->source();
3799 if (!src->IsString()) return true;
3800 String* src_str = String::cast(src);
3801 if (!StringShape(src_str).IsExternal()) return true;
3802 if (src_str->IsAsciiRepresentation()) {
3803 return ExternalAsciiString::cast(src)->resource() != NULL;
3804 } else if (src_str->IsTwoByteRepresentation()) {
3805 return ExternalTwoByteString::cast(src)->resource() != NULL;
3806 }
3807 return true;
3808}
3809
3810
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003811void SharedFunctionInfo::DontAdaptArguments() {
3812 ASSERT(code()->kind() == Code::BUILTIN);
3813 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3814}
3815
3816
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003817int SharedFunctionInfo::start_position() {
3818 return start_position_and_type() >> kStartPositionShift;
3819}
3820
3821
3822void SharedFunctionInfo::set_start_position(int start_position) {
3823 set_start_position_and_type((start_position << kStartPositionShift)
3824 | (start_position_and_type() & ~kStartPositionMask));
3825}
3826
3827
3828Code* SharedFunctionInfo::code() {
3829 return Code::cast(READ_FIELD(this, kCodeOffset));
3830}
3831
3832
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003833Code* SharedFunctionInfo::unchecked_code() {
3834 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3835}
3836
3837
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003838void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003839 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003840 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003841}
3842
3843
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003844ScopeInfo* SharedFunctionInfo::scope_info() {
3845 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003846}
3847
3848
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003849void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003850 WriteBarrierMode mode) {
3851 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003852 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3853 this,
3854 kScopeInfoOffset,
3855 reinterpret_cast<Object*>(value),
3856 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003857}
3858
3859
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003860bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003861 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003862 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003863}
3864
3865
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003866bool SharedFunctionInfo::IsApiFunction() {
3867 return function_data()->IsFunctionTemplateInfo();
3868}
3869
3870
3871FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3872 ASSERT(IsApiFunction());
3873 return FunctionTemplateInfo::cast(function_data());
3874}
3875
3876
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003877bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003878 return function_data()->IsSmi();
3879}
3880
3881
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003882BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3883 ASSERT(HasBuiltinFunctionId());
3884 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003885}
3886
3887
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003888int SharedFunctionInfo::code_age() {
3889 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3890}
3891
3892
3893void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00003894 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3895 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003896}
3897
3898
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003899bool SharedFunctionInfo::has_deoptimization_support() {
3900 Code* code = this->code();
3901 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3902}
3903
3904
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003905bool JSFunction::IsBuiltin() {
3906 return context()->global()->IsJSBuiltinsObject();
3907}
3908
3909
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003910bool JSFunction::NeedsArgumentsAdaption() {
3911 return shared()->formal_parameter_count() !=
3912 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3913}
3914
3915
3916bool JSFunction::IsOptimized() {
3917 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3918}
3919
3920
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003921bool JSFunction::IsOptimizable() {
3922 return code()->kind() == Code::FUNCTION && code()->optimizable();
3923}
3924
3925
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003926bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003927 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003928}
3929
3930
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003931Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003932 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003933}
3934
3935
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003936Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003937 return reinterpret_cast<Code*>(
3938 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003939}
3940
3941
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003942void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003943 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003944 Address entry = value->entry();
3945 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003946 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3947 this,
3948 HeapObject::RawField(this, kCodeEntryOffset),
3949 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003950}
3951
3952
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003953void JSFunction::ReplaceCode(Code* code) {
3954 bool was_optimized = IsOptimized();
3955 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3956
3957 set_code(code);
3958
3959 // Add/remove the function from the list of optimized functions for this
3960 // context based on the state change.
3961 if (!was_optimized && is_optimized) {
3962 context()->global_context()->AddOptimizedFunction(this);
3963 }
3964 if (was_optimized && !is_optimized) {
3965 context()->global_context()->RemoveOptimizedFunction(this);
3966 }
3967}
3968
3969
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003970Context* JSFunction::context() {
3971 return Context::cast(READ_FIELD(this, kContextOffset));
3972}
3973
3974
3975Object* JSFunction::unchecked_context() {
3976 return READ_FIELD(this, kContextOffset);
3977}
3978
3979
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003980SharedFunctionInfo* JSFunction::unchecked_shared() {
3981 return reinterpret_cast<SharedFunctionInfo*>(
3982 READ_FIELD(this, kSharedFunctionInfoOffset));
3983}
3984
3985
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003986void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003987 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003988 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003989 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003990}
3991
3992ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3993 kPrototypeOrInitialMapOffset)
3994
3995
3996Map* JSFunction::initial_map() {
3997 return Map::cast(prototype_or_initial_map());
3998}
3999
4000
4001void JSFunction::set_initial_map(Map* value) {
4002 set_prototype_or_initial_map(value);
4003}
4004
4005
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004006MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
4007 Map* initial_map) {
4008 Context* global_context = context()->global_context();
4009 Object* array_function =
4010 global_context->get(Context::ARRAY_FUNCTION_INDEX);
4011 if (array_function->IsJSFunction() &&
4012 this == JSFunction::cast(array_function)) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004013 // Replace all of the cached initial array maps in the global context with
4014 // the appropriate transitioned elements kind maps.
4015 Heap* heap = GetHeap();
4016 MaybeObject* maybe_maps =
4017 heap->AllocateFixedArrayWithHoles(kElementsKindCount);
4018 FixedArray* maps;
4019 if (!maybe_maps->To(&maps)) return maybe_maps;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004020
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004021 Map* current_map = initial_map;
4022 ElementsKind kind = current_map->elements_kind();
4023 ASSERT(kind == GetInitialFastElementsKind());
4024 maps->set(kind, current_map);
4025 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
4026 i < kFastElementsKindCount; ++i) {
4027 ElementsKind transitioned_kind = GetFastElementsKindFromSequenceIndex(i);
4028 MaybeObject* maybe_new_map = current_map->CopyDropTransitions();
4029 Map* new_map = NULL;
4030 if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map;
4031 new_map->set_elements_kind(transitioned_kind);
4032 maybe_new_map = current_map->AddElementsTransition(transitioned_kind,
4033 new_map);
4034 if (maybe_new_map->IsFailure()) return maybe_new_map;
4035 maps->set(transitioned_kind, new_map);
4036 current_map = new_map;
4037 }
4038 global_context->set_js_array_maps(maps);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004039 }
4040 set_initial_map(initial_map);
4041 return this;
4042}
4043
4044
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004045bool JSFunction::has_initial_map() {
4046 return prototype_or_initial_map()->IsMap();
4047}
4048
4049
4050bool JSFunction::has_instance_prototype() {
4051 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4052}
4053
4054
4055bool JSFunction::has_prototype() {
4056 return map()->has_non_instance_prototype() || has_instance_prototype();
4057}
4058
4059
4060Object* JSFunction::instance_prototype() {
4061 ASSERT(has_instance_prototype());
4062 if (has_initial_map()) return initial_map()->prototype();
4063 // When there is no initial map and the prototype is a JSObject, the
4064 // initial map field is used for the prototype field.
4065 return prototype_or_initial_map();
4066}
4067
4068
4069Object* JSFunction::prototype() {
4070 ASSERT(has_prototype());
4071 // If the function's prototype property has been set to a non-JSObject
4072 // value, that value is stored in the constructor field of the map.
4073 if (map()->has_non_instance_prototype()) return map()->constructor();
4074 return instance_prototype();
4075}
4076
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00004077bool JSFunction::should_have_prototype() {
4078 return map()->function_with_prototype();
4079}
4080
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004081
4082bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004083 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004084}
4085
4086
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004087FixedArray* JSFunction::literals() {
4088 ASSERT(!shared()->bound());
4089 return literals_or_bindings();
4090}
4091
4092
4093void JSFunction::set_literals(FixedArray* literals) {
4094 ASSERT(!shared()->bound());
4095 set_literals_or_bindings(literals);
4096}
4097
4098
4099FixedArray* JSFunction::function_bindings() {
4100 ASSERT(shared()->bound());
4101 return literals_or_bindings();
4102}
4103
4104
4105void JSFunction::set_function_bindings(FixedArray* bindings) {
4106 ASSERT(shared()->bound());
4107 // Bound function literal may be initialized to the empty fixed array
4108 // before the bindings are set.
4109 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4110 bindings->map() == GetHeap()->fixed_cow_array_map());
4111 set_literals_or_bindings(bindings);
4112}
4113
4114
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004115int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004116 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004117 return literals()->length();
4118}
4119
4120
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004121Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004122 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004123 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004124}
4125
4126
4127void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4128 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004129 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004130 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004131 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004132}
4133
4134
4135Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004136 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004137 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4138}
4139
4140
4141void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4142 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004143 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004144 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004145 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004146}
4147
4148
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004149ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004150ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004151ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4152ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4153
4154
4155void JSProxy::InitializeBody(int object_size, Object* value) {
4156 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4157 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4158 WRITE_FIELD(this, offset, value);
4159 }
4160}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004161
4162
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004163ACCESSORS(JSSet, table, Object, kTableOffset)
4164ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004165ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4166ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004167
4168
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004169Address Foreign::foreign_address() {
4170 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004171}
4172
4173
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004174void Foreign::set_foreign_address(Address value) {
4175 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004176}
4177
4178
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004179ACCESSORS(JSModule, context, Object, kContextOffset)
4180
4181
4182JSModule* JSModule::cast(Object* obj) {
4183 ASSERT(obj->IsJSModule());
4184 ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
4185 return reinterpret_cast<JSModule*>(obj);
4186}
4187
4188
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004189ACCESSORS(JSValue, value, Object, kValueOffset)
4190
4191
4192JSValue* JSValue::cast(Object* obj) {
4193 ASSERT(obj->IsJSValue());
4194 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4195 return reinterpret_cast<JSValue*>(obj);
4196}
4197
4198
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004199ACCESSORS(JSDate, value, Object, kValueOffset)
4200ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4201ACCESSORS(JSDate, year, Object, kYearOffset)
4202ACCESSORS(JSDate, month, Object, kMonthOffset)
4203ACCESSORS(JSDate, day, Object, kDayOffset)
4204ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4205ACCESSORS(JSDate, hour, Object, kHourOffset)
4206ACCESSORS(JSDate, min, Object, kMinOffset)
4207ACCESSORS(JSDate, sec, Object, kSecOffset)
4208
4209
4210JSDate* JSDate::cast(Object* obj) {
4211 ASSERT(obj->IsJSDate());
4212 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4213 return reinterpret_cast<JSDate*>(obj);
4214}
4215
4216
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004217ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4218ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4219ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4220ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4221ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4222SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4223SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4224
4225
4226JSMessageObject* JSMessageObject::cast(Object* obj) {
4227 ASSERT(obj->IsJSMessageObject());
4228 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4229 return reinterpret_cast<JSMessageObject*>(obj);
4230}
4231
4232
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004233INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004234ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004235ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004236ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004237ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004238ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00004239INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004240
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004241byte* Code::instruction_start() {
4242 return FIELD_ADDR(this, kHeaderSize);
4243}
4244
4245
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004246byte* Code::instruction_end() {
4247 return instruction_start() + instruction_size();
4248}
4249
4250
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004251int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004252 return RoundUp(instruction_size(), kObjectAlignment);
4253}
4254
4255
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004256FixedArray* Code::unchecked_deoptimization_data() {
4257 return reinterpret_cast<FixedArray*>(
4258 READ_FIELD(this, kDeoptimizationDataOffset));
4259}
4260
4261
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004262ByteArray* Code::unchecked_relocation_info() {
4263 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004264}
4265
4266
4267byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004268 return unchecked_relocation_info()->GetDataStartAddress();
4269}
4270
4271
4272int Code::relocation_size() {
4273 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004274}
4275
4276
4277byte* Code::entry() {
4278 return instruction_start();
4279}
4280
4281
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004282bool Code::contains(byte* inner_pointer) {
4283 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004284}
4285
4286
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004287ACCESSORS(JSArray, length, Object, kLengthOffset)
4288
4289
ager@chromium.org236ad962008-09-25 09:45:57 +00004290ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004291
4292
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004293JSRegExp::Type JSRegExp::TypeTag() {
4294 Object* data = this->data();
4295 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4296 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4297 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004298}
4299
4300
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004301JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4302 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4303 return static_cast<JSRegExp::Type>(smi->value());
4304}
4305
4306
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004307int JSRegExp::CaptureCount() {
4308 switch (TypeTag()) {
4309 case ATOM:
4310 return 0;
4311 case IRREGEXP:
4312 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4313 default:
4314 UNREACHABLE();
4315 return -1;
4316 }
4317}
4318
4319
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004320JSRegExp::Flags JSRegExp::GetFlags() {
4321 ASSERT(this->data()->IsFixedArray());
4322 Object* data = this->data();
4323 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4324 return Flags(smi->value());
4325}
4326
4327
4328String* JSRegExp::Pattern() {
4329 ASSERT(this->data()->IsFixedArray());
4330 Object* data = this->data();
4331 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4332 return pattern;
4333}
4334
4335
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004336Object* JSRegExp::DataAt(int index) {
4337 ASSERT(TypeTag() != NOT_COMPILED);
4338 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004339}
4340
4341
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004342Object* JSRegExp::DataAtUnchecked(int index) {
4343 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4344 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4345 return READ_FIELD(fa, offset);
4346}
4347
4348
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004349void JSRegExp::SetDataAt(int index, Object* value) {
4350 ASSERT(TypeTag() != NOT_COMPILED);
4351 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4352 FixedArray::cast(data())->set(index, value);
4353}
4354
4355
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004356void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4357 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4358 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4359 if (value->IsSmi()) {
4360 fa->set_unchecked(index, Smi::cast(value));
4361 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004362 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004363 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4364 }
4365}
4366
4367
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004368ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004369 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004370#if DEBUG
4371 FixedArrayBase* fixed_array =
4372 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4373 Map* map = fixed_array->map();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004374 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
4375 (map == GetHeap()->fixed_array_map() ||
4376 map == GetHeap()->fixed_cow_array_map())) ||
4377 (IsFastDoubleElementsKind(kind) &&
4378 (fixed_array->IsFixedDoubleArray() ||
4379 fixed_array == GetHeap()->empty_fixed_array())) ||
4380 (kind == DICTIONARY_ELEMENTS &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004381 fixed_array->IsFixedArray() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004382 fixed_array->IsDictionary()) ||
4383 (kind > DICTIONARY_ELEMENTS));
4384 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4385 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004386#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004387 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004388}
4389
4390
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004391ElementsAccessor* JSObject::GetElementsAccessor() {
4392 return ElementsAccessor::ForKind(GetElementsKind());
4393}
4394
4395
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004396bool JSObject::HasFastObjectElements() {
4397 return IsFastObjectElementsKind(GetElementsKind());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004398}
4399
4400
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004401bool JSObject::HasFastSmiElements() {
4402 return IsFastSmiElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004403}
4404
4405
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004406bool JSObject::HasFastSmiOrObjectElements() {
4407 return IsFastSmiOrObjectElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004408}
4409
4410
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004411bool JSObject::HasFastDoubleElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004412 return IsFastDoubleElementsKind(GetElementsKind());
4413}
4414
4415
4416bool JSObject::HasFastHoleyElements() {
4417 return IsFastHoleyElementsKind(GetElementsKind());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004418}
4419
4420
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004421bool JSObject::HasDictionaryElements() {
4422 return GetElementsKind() == DICTIONARY_ELEMENTS;
4423}
4424
4425
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004426bool JSObject::HasNonStrictArgumentsElements() {
4427 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4428}
4429
4430
ager@chromium.org3811b432009-10-28 14:53:37 +00004431bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004432 HeapObject* array = elements();
4433 ASSERT(array != NULL);
4434 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004435}
4436
4437
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004438#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4439bool JSObject::HasExternal##name##Elements() { \
4440 HeapObject* array = elements(); \
4441 ASSERT(array != NULL); \
4442 if (!array->IsHeapObject()) \
4443 return false; \
4444 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004445}
4446
4447
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004448EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4449EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4450EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4451EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4452 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4453EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4454EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4455 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4456EXTERNAL_ELEMENTS_CHECK(Float,
4457 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004458EXTERNAL_ELEMENTS_CHECK(Double,
4459 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004460EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004461
4462
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004463bool JSObject::HasNamedInterceptor() {
4464 return map()->has_named_interceptor();
4465}
4466
4467
4468bool JSObject::HasIndexedInterceptor() {
4469 return map()->has_indexed_interceptor();
4470}
4471
4472
lrn@chromium.org303ada72010-10-27 09:33:13 +00004473MaybeObject* JSObject::EnsureWritableFastElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004474 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004475 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004476 Isolate* isolate = GetIsolate();
4477 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004478 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004479 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4480 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004481 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4482 return maybe_writable_elems;
4483 }
4484 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004485 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004486 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004487 return writable_elems;
4488}
4489
4490
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004491StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004492 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004493 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004494}
4495
4496
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004497SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004498 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004499 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004500}
4501
4502
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004503bool String::IsHashFieldComputed(uint32_t field) {
4504 return (field & kHashNotComputedMask) == 0;
4505}
4506
4507
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004508bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004509 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004510}
4511
4512
4513uint32_t String::Hash() {
4514 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004515 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004516 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004517 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004518 return ComputeAndSetHash();
4519}
4520
4521
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004522StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004523 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004524 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004525 array_index_(0),
4526 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4527 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004528 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004529 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004530}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004531
4532
4533bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004534 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004535}
4536
4537
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004538void StringHasher::AddCharacter(uint32_t c) {
4539 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4540 AddSurrogatePair(c); // Not inlined.
4541 return;
4542 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004543 // Use the Jenkins one-at-a-time hash function to update the hash
4544 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004545 raw_running_hash_ += c;
4546 raw_running_hash_ += (raw_running_hash_ << 10);
4547 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004548 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004549 if (is_array_index_) {
4550 if (c < '0' || c > '9') {
4551 is_array_index_ = false;
4552 } else {
4553 int d = c - '0';
4554 if (is_first_char_) {
4555 is_first_char_ = false;
4556 if (c == '0' && length_ > 1) {
4557 is_array_index_ = false;
4558 return;
4559 }
4560 }
4561 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4562 is_array_index_ = false;
4563 } else {
4564 array_index_ = array_index_ * 10 + d;
4565 }
4566 }
4567 }
4568}
4569
4570
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004571void StringHasher::AddCharacterNoIndex(uint32_t c) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00004572 ASSERT(!is_array_index());
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004573 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4574 AddSurrogatePairNoIndex(c); // Not inlined.
4575 return;
4576 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004577 raw_running_hash_ += c;
4578 raw_running_hash_ += (raw_running_hash_ << 10);
4579 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4580}
4581
4582
4583uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004584 // Get the calculated raw hash value and do some more bit ops to distribute
4585 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004586 uint32_t result = raw_running_hash_;
4587 result += (result << 3);
4588 result ^= (result >> 11);
4589 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004590 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004591 result = 27;
4592 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004593 return result;
4594}
4595
4596
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004597template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004598uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4599 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004600 if (!hasher.has_trivial_hash()) {
4601 int i;
4602 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4603 hasher.AddCharacter(chars[i]);
4604 }
4605 for (; i < length; i++) {
4606 hasher.AddCharacterNoIndex(chars[i]);
4607 }
4608 }
4609 return hasher.GetHashField();
4610}
4611
4612
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004613bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004614 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004615 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4616 return false;
4617 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004618 return SlowAsArrayIndex(index);
4619}
4620
4621
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004622Object* JSReceiver::GetPrototype() {
4623 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004624}
4625
4626
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004627bool JSReceiver::HasProperty(String* name) {
4628 if (IsJSProxy()) {
4629 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4630 }
4631 return GetPropertyAttribute(name) != ABSENT;
4632}
4633
4634
4635bool JSReceiver::HasLocalProperty(String* name) {
4636 if (IsJSProxy()) {
4637 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4638 }
4639 return GetLocalPropertyAttribute(name) != ABSENT;
4640}
4641
4642
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004643PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004644 return GetPropertyAttributeWithReceiver(this, key);
4645}
4646
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004647// TODO(504): this may be useful in other places too where JSGlobalProxy
4648// is used.
4649Object* JSObject::BypassGlobalProxy() {
4650 if (IsJSGlobalProxy()) {
4651 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004652 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004653 ASSERT(proto->IsJSGlobalObject());
4654 return proto;
4655 }
4656 return this;
4657}
4658
4659
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004660MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4661 return IsJSProxy()
4662 ? JSProxy::cast(this)->GetIdentityHash(flag)
4663 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004664}
4665
4666
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004667bool JSReceiver::HasElement(uint32_t index) {
4668 if (IsJSProxy()) {
4669 return JSProxy::cast(this)->HasElementWithHandler(index);
4670 }
4671 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004672}
4673
4674
4675bool AccessorInfo::all_can_read() {
4676 return BooleanBit::get(flag(), kAllCanReadBit);
4677}
4678
4679
4680void AccessorInfo::set_all_can_read(bool value) {
4681 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4682}
4683
4684
4685bool AccessorInfo::all_can_write() {
4686 return BooleanBit::get(flag(), kAllCanWriteBit);
4687}
4688
4689
4690void AccessorInfo::set_all_can_write(bool value) {
4691 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4692}
4693
4694
ager@chromium.org870a0b62008-11-04 11:43:05 +00004695bool AccessorInfo::prohibits_overwriting() {
4696 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4697}
4698
4699
4700void AccessorInfo::set_prohibits_overwriting(bool value) {
4701 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4702}
4703
4704
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004705PropertyAttributes AccessorInfo::property_attributes() {
4706 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4707}
4708
4709
4710void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004711 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004712}
4713
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004714
4715template<typename Shape, typename Key>
4716void Dictionary<Shape, Key>::SetEntry(int entry,
4717 Object* key,
4718 Object* value) {
4719 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4720}
4721
4722
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004723template<typename Shape, typename Key>
4724void Dictionary<Shape, Key>::SetEntry(int entry,
4725 Object* key,
4726 Object* value,
4727 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004728 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004729 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004730 AssertNoAllocation no_gc;
4731 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004732 FixedArray::set(index, key, mode);
4733 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004734 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004735}
4736
4737
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004738bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4739 ASSERT(other->IsNumber());
4740 return key == static_cast<uint32_t>(other->Number());
4741}
4742
4743
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004744uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
4745 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004746}
4747
4748
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004749uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
4750 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004751 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004752 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004753}
4754
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004755uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
4756 return ComputeIntegerHash(key, seed);
4757}
4758
4759uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
4760 uint32_t seed,
4761 Object* other) {
4762 ASSERT(other->IsNumber());
4763 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
4764}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004765
4766MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4767 return Isolate::Current()->heap()->NumberFromUint32(key);
4768}
4769
4770
4771bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4772 // We know that all entries in a hash table had their hash keys created.
4773 // Use that knowledge to have fast failure.
4774 if (key->Hash() != String::cast(other)->Hash()) return false;
4775 return key->Equals(String::cast(other));
4776}
4777
4778
4779uint32_t StringDictionaryShape::Hash(String* key) {
4780 return key->Hash();
4781}
4782
4783
4784uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4785 return String::cast(other)->Hash();
4786}
4787
4788
4789MaybeObject* StringDictionaryShape::AsObject(String* key) {
4790 return key;
4791}
4792
4793
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004794template <int entrysize>
4795bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4796 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004797}
4798
4799
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004800template <int entrysize>
4801uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004802 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4803 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004804}
4805
4806
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004807template <int entrysize>
4808uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4809 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004810 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4811 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004812}
4813
4814
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004815template <int entrysize>
4816MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004817 return key;
4818}
4819
4820
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004821void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004822 // No write barrier is needed since empty_fixed_array is not in new space.
4823 // Please note this function is used during marking:
4824 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00004825 // - IncrementalMarking::Step
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004826 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4827 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004828}
4829
4830
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004831void JSArray::EnsureSize(int required_size) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004832 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004833 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004834 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4835 if (elts->length() < required_size) {
4836 // Doubling in size would be overkill, but leave some slack to avoid
4837 // constantly growing.
4838 Expand(required_size + (required_size >> 3));
4839 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004840 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004841 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4842 // Expand will allocate a new backing store in new space even if the size
4843 // we asked for isn't larger than what we had before.
4844 Expand(required_size);
4845 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004846}
4847
4848
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004849void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004850 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004851 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4852}
4853
4854
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004855bool JSArray::AllowsSetElementsLength() {
4856 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4857 ASSERT(result == !HasExternalArrayElements());
4858 return result;
4859}
4860
4861
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004862MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4863 MaybeObject* maybe_result = EnsureCanContainElements(
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004864 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004865 if (maybe_result->IsFailure()) return maybe_result;
4866 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004867 IsFastDoubleElementsKind(GetElementsKind())) ||
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004868 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004869 (IsFastObjectElementsKind(GetElementsKind()) ||
4870 (IsFastSmiElementsKind(GetElementsKind()) &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004871 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004872 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004873 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004874 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004875}
4876
4877
lrn@chromium.org303ada72010-10-27 09:33:13 +00004878MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004879 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004880 return GetHeap()->CopyFixedArray(this);
4881}
4882
4883
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004884MaybeObject* FixedDoubleArray::Copy() {
4885 if (length() == 0) return this;
4886 return GetHeap()->CopyFixedDoubleArray(this);
4887}
4888
4889
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004890void TypeFeedbackCells::SetAstId(int index, Smi* id) {
4891 set(1 + index * 2, id);
4892}
4893
4894
4895Smi* TypeFeedbackCells::AstId(int index) {
4896 return Smi::cast(get(1 + index * 2));
4897}
4898
4899
4900void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
4901 set(index * 2, cell);
4902}
4903
4904
4905JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
4906 return JSGlobalPropertyCell::cast(get(index * 2));
4907}
4908
4909
4910Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
4911 return isolate->factory()->the_hole_value();
4912}
4913
4914
4915Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
4916 return isolate->factory()->undefined_value();
4917}
4918
4919
4920Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
4921 return heap->raw_unchecked_the_hole_value();
4922}
4923
4924
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004925SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00004926SMI_ACCESSORS(TypeFeedbackInfo, ic_with_type_info_count,
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004927 kIcWithTypeinfoCountOffset)
4928ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
4929 kTypeFeedbackCellsOffset)
4930
4931
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00004932SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
4933
4934
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004935Relocatable::Relocatable(Isolate* isolate) {
4936 ASSERT(isolate == Isolate::Current());
4937 isolate_ = isolate;
4938 prev_ = isolate->relocatable_top();
4939 isolate->set_relocatable_top(this);
4940}
4941
4942
4943Relocatable::~Relocatable() {
4944 ASSERT(isolate_ == Isolate::Current());
4945 ASSERT_EQ(isolate_->relocatable_top(), this);
4946 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004947}
4948
4949
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004950int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4951 return map->instance_size();
4952}
4953
4954
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004955void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004956 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004957 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004958}
4959
4960
4961template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004962void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004963 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004964 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004965}
4966
4967
4968void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4969 typedef v8::String::ExternalAsciiStringResource Resource;
4970 v->VisitExternalAsciiString(
4971 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4972}
4973
4974
4975template<typename StaticVisitor>
4976void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4977 typedef v8::String::ExternalAsciiStringResource Resource;
4978 StaticVisitor::VisitExternalAsciiString(
4979 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4980}
4981
4982
4983void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4984 typedef v8::String::ExternalStringResource Resource;
4985 v->VisitExternalTwoByteString(
4986 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4987}
4988
4989
4990template<typename StaticVisitor>
4991void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4992 typedef v8::String::ExternalStringResource Resource;
4993 StaticVisitor::VisitExternalTwoByteString(
4994 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4995}
4996
4997#define SLOT_ADDR(obj, offset) \
4998 reinterpret_cast<Object**>((obj)->address() + offset)
4999
5000template<int start_offset, int end_offset, int size>
5001void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
5002 HeapObject* obj,
5003 ObjectVisitor* v) {
5004 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
5005}
5006
5007
5008template<int start_offset>
5009void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
5010 int object_size,
5011 ObjectVisitor* v) {
5012 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
5013}
5014
5015#undef SLOT_ADDR
5016
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005017#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005018#undef CAST_ACCESSOR
5019#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005020#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005021#undef ACCESSORS_TO_SMI
5022#undef SMI_ACCESSORS
5023#undef BOOL_GETTER
5024#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005025#undef FIELD_ADDR
5026#undef READ_FIELD
5027#undef WRITE_FIELD
5028#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005029#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005030#undef READ_DOUBLE_FIELD
5031#undef WRITE_DOUBLE_FIELD
5032#undef READ_INT_FIELD
5033#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005034#undef READ_INTPTR_FIELD
5035#undef WRITE_INTPTR_FIELD
5036#undef READ_UINT32_FIELD
5037#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005038#undef READ_SHORT_FIELD
5039#undef WRITE_SHORT_FIELD
5040#undef READ_BYTE_FIELD
5041#undef WRITE_BYTE_FIELD
5042
5043
5044} } // namespace v8::internal
5045
5046#endif // V8_OBJECTS_INL_H_