blob: 074f1ed0421b8215d014a867cf2544ec078b40a0 [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();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001270 for (uint32_t i = 0; i < count; ++i) {
1271 Object* current = *objects++;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001272 if (current == the_hole) {
1273 is_holey = true;
1274 target_kind = GetHoleyElementsKind(target_kind);
1275 } else if (!current->IsSmi()) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001276 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && current->IsNumber()) {
1277 if (IsFastSmiElementsKind(target_kind)) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001278 if (is_holey) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001279 target_kind = FAST_HOLEY_DOUBLE_ELEMENTS;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001280 } else {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001281 target_kind = FAST_DOUBLE_ELEMENTS;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001282 }
1283 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001284 } else if (is_holey) {
1285 target_kind = FAST_HOLEY_ELEMENTS;
1286 break;
1287 } else {
1288 target_kind = FAST_ELEMENTS;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001289 }
1290 }
1291 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001292
1293 if (target_kind != current_kind) {
1294 return TransitionElementsKind(target_kind);
1295 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001296 return this;
1297}
1298
1299
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001300MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001301 uint32_t length,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001302 EnsureElementsMode mode) {
1303 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1304 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1305 elements->map() == GetHeap()->fixed_cow_array_map());
1306 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1307 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1308 }
1309 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001310 return EnsureCanContainElements(objects, length, mode);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001311 }
1312
1313 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001314 if (GetElementsKind() == FAST_HOLEY_SMI_ELEMENTS) {
1315 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS);
1316 } else if (GetElementsKind() == FAST_SMI_ELEMENTS) {
1317 FixedDoubleArray* double_array = FixedDoubleArray::cast(elements);
1318 for (uint32_t i = 0; i < length; ++i) {
1319 if (double_array->is_the_hole(i)) {
1320 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS);
1321 }
1322 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001323 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1324 }
1325
1326 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001327}
1328
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001329
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001330MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
1331 ElementsKind to_kind) {
1332 Map* current_map = map();
1333 ElementsKind from_kind = current_map->elements_kind();
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001334 if (from_kind == to_kind) return current_map;
1335
1336 Context* global_context = isolate->context()->global_context();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001337 Object* maybe_array_maps = global_context->js_array_maps();
1338 if (maybe_array_maps->IsFixedArray()) {
1339 FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
1340 if (array_maps->get(from_kind) == current_map) {
1341 Object* maybe_transitioned_map = array_maps->get(to_kind);
1342 if (maybe_transitioned_map->IsMap()) {
1343 return Map::cast(maybe_transitioned_map);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001344 }
1345 }
1346 }
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001347
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001348 return GetElementsTransitionMapSlow(to_kind);
1349}
1350
1351
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001352void JSObject::set_map_and_elements(Map* new_map,
1353 FixedArrayBase* value,
1354 WriteBarrierMode mode) {
1355 ASSERT(value->HasValidElements());
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001356 if (new_map != NULL) {
1357 if (mode == UPDATE_WRITE_BARRIER) {
1358 set_map(new_map);
1359 } else {
1360 ASSERT(mode == SKIP_WRITE_BARRIER);
1361 set_map_no_write_barrier(new_map);
1362 }
1363 }
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001364 ASSERT((map()->has_fast_smi_or_object_elements() ||
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001365 (value == GetHeap()->empty_fixed_array())) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001366 (value->map() == GetHeap()->fixed_array_map() ||
1367 value->map() == GetHeap()->fixed_cow_array_map()));
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001368 ASSERT((value == GetHeap()->empty_fixed_array()) ||
1369 (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001370 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001371 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001372}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001373
1374
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001375void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1376 set_map_and_elements(NULL, value, mode);
1377}
1378
1379
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001380void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001381 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1382 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001383}
1384
1385
1386void JSObject::initialize_elements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001387 ASSERT(map()->has_fast_smi_or_object_elements() ||
danno@chromium.org2c26cb12012-05-03 09:06:43 +00001388 map()->has_fast_double_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001389 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1390 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001391}
1392
1393
lrn@chromium.org303ada72010-10-27 09:33:13 +00001394MaybeObject* JSObject::ResetElements() {
1395 Object* obj;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001396 ElementsKind elements_kind = GetInitialFastElementsKind();
1397 if (!FLAG_smi_only_arrays) {
1398 elements_kind = FastSmiToObjectElementsKind(elements_kind);
1399 }
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001400 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(),
1401 elements_kind);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001402 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001403 set_map(Map::cast(obj));
1404 initialize_elements();
1405 return this;
1406}
1407
1408
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001409ACCESSORS(Oddball, to_string, String, kToStringOffset)
1410ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1411
1412
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001413byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001414 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001415}
1416
1417
1418void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001419 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001420}
1421
1422
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001423Object* JSGlobalPropertyCell::value() {
1424 return READ_FIELD(this, kValueOffset);
1425}
1426
1427
1428void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1429 // The write barrier is not used for global property cells.
1430 ASSERT(!val->IsJSGlobalPropertyCell());
1431 WRITE_FIELD(this, kValueOffset, val);
1432}
1433
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001434
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001435int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001436 InstanceType type = map()->instance_type();
1437 // Check for the most common kind of JavaScript object before
1438 // falling into the generic switch. This speeds up the internal
1439 // field operations considerably on average.
1440 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1441 switch (type) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001442 case JS_MODULE_TYPE:
1443 return JSModule::kSize;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001444 case JS_GLOBAL_PROXY_TYPE:
1445 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001446 case JS_GLOBAL_OBJECT_TYPE:
1447 return JSGlobalObject::kSize;
1448 case JS_BUILTINS_OBJECT_TYPE:
1449 return JSBuiltinsObject::kSize;
1450 case JS_FUNCTION_TYPE:
1451 return JSFunction::kSize;
1452 case JS_VALUE_TYPE:
1453 return JSValue::kSize;
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00001454 case JS_DATE_TYPE:
1455 return JSDate::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001456 case JS_ARRAY_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001457 return JSArray::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001458 case JS_WEAK_MAP_TYPE:
1459 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001460 case JS_REGEXP_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001461 return JSRegExp::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001462 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001463 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001464 case JS_MESSAGE_OBJECT_TYPE:
1465 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001466 default:
1467 UNREACHABLE();
1468 return 0;
1469 }
1470}
1471
1472
1473int JSObject::GetInternalFieldCount() {
1474 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001475 // Make sure to adjust for the number of in-object properties. These
1476 // properties do contribute to the size, but are not internal fields.
1477 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1478 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001479}
1480
1481
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001482int JSObject::GetInternalFieldOffset(int index) {
1483 ASSERT(index < GetInternalFieldCount() && index >= 0);
1484 return GetHeaderSize() + (kPointerSize * index);
1485}
1486
1487
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001488Object* JSObject::GetInternalField(int index) {
1489 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001490 // Internal objects do follow immediately after the header, whereas in-object
1491 // properties are at the end of the object. Therefore there is no need
1492 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001493 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1494}
1495
1496
1497void JSObject::SetInternalField(int index, Object* value) {
1498 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001499 // Internal objects do follow immediately after the header, whereas in-object
1500 // properties are at the end of the object. Therefore there is no need
1501 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001502 int offset = GetHeaderSize() + (kPointerSize * index);
1503 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001504 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001505}
1506
1507
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001508void JSObject::SetInternalField(int index, Smi* value) {
1509 ASSERT(index < GetInternalFieldCount() && index >= 0);
1510 // Internal objects do follow immediately after the header, whereas in-object
1511 // properties are at the end of the object. Therefore there is no need
1512 // to adjust the index here.
1513 int offset = GetHeaderSize() + (kPointerSize * index);
1514 WRITE_FIELD(this, offset, value);
1515}
1516
1517
ager@chromium.org7c537e22008-10-16 08:43:32 +00001518// Access fast-case object properties at index. The use of these routines
1519// is needed to correctly distinguish between properties stored in-object and
1520// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001521Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001522 // Adjust for the number of properties stored in the object.
1523 index -= map()->inobject_properties();
1524 if (index < 0) {
1525 int offset = map()->instance_size() + (index * kPointerSize);
1526 return READ_FIELD(this, offset);
1527 } else {
1528 ASSERT(index < properties()->length());
1529 return properties()->get(index);
1530 }
1531}
1532
1533
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001534Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001535 // Adjust for the number of properties stored in the object.
1536 index -= map()->inobject_properties();
1537 if (index < 0) {
1538 int offset = map()->instance_size() + (index * kPointerSize);
1539 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001540 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001541 } else {
1542 ASSERT(index < properties()->length());
1543 properties()->set(index, value);
1544 }
1545 return value;
1546}
1547
1548
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001549int JSObject::GetInObjectPropertyOffset(int index) {
1550 // Adjust for the number of properties stored in the object.
1551 index -= map()->inobject_properties();
1552 ASSERT(index < 0);
1553 return map()->instance_size() + (index * kPointerSize);
1554}
1555
1556
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001557Object* JSObject::InObjectPropertyAt(int index) {
1558 // Adjust for the number of properties stored in the object.
1559 index -= map()->inobject_properties();
1560 ASSERT(index < 0);
1561 int offset = map()->instance_size() + (index * kPointerSize);
1562 return READ_FIELD(this, offset);
1563}
1564
1565
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001566Object* JSObject::InObjectPropertyAtPut(int index,
1567 Object* value,
1568 WriteBarrierMode mode) {
1569 // Adjust for the number of properties stored in the object.
1570 index -= map()->inobject_properties();
1571 ASSERT(index < 0);
1572 int offset = map()->instance_size() + (index * kPointerSize);
1573 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001574 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001575 return value;
1576}
1577
1578
1579
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001580void JSObject::InitializeBody(Map* map,
1581 Object* pre_allocated_value,
1582 Object* filler_value) {
1583 ASSERT(!filler_value->IsHeapObject() ||
1584 !GetHeap()->InNewSpace(filler_value));
1585 ASSERT(!pre_allocated_value->IsHeapObject() ||
1586 !GetHeap()->InNewSpace(pre_allocated_value));
1587 int size = map->instance_size();
1588 int offset = kHeaderSize;
1589 if (filler_value != pre_allocated_value) {
1590 int pre_allocated = map->pre_allocated_property_fields();
1591 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1592 for (int i = 0; i < pre_allocated; i++) {
1593 WRITE_FIELD(this, offset, pre_allocated_value);
1594 offset += kPointerSize;
1595 }
1596 }
1597 while (offset < size) {
1598 WRITE_FIELD(this, offset, filler_value);
1599 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001600 }
1601}
1602
1603
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001604bool JSObject::HasFastProperties() {
1605 return !properties()->IsDictionary();
1606}
1607
1608
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001609bool JSObject::TooManyFastProperties(int properties,
1610 JSObject::StoreFromKeyed store_mode) {
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001611 // Allow extra fast properties if the object has more than
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001612 // kFastPropertiesSoftLimit in-object properties. When this is the case,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001613 // it is very unlikely that the object is being used as a dictionary
1614 // and there is a good chance that allowing more map transitions
1615 // will be worth it.
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001616 int inobject = map()->inobject_properties();
1617
1618 int limit;
ulan@chromium.orgf6a0c412012-06-15 12:31:06 +00001619 if (store_mode == CERTAINLY_NOT_STORE_FROM_KEYED) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001620 limit = Max(inobject, kMaxFastProperties);
1621 } else {
1622 limit = Max(inobject, kFastPropertiesSoftLimit);
1623 }
1624 return properties > limit;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001625}
1626
1627
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001628void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001629 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001630 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001631 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001632 }
1633}
1634
1635
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001636bool Object::ToArrayIndex(uint32_t* index) {
1637 if (IsSmi()) {
1638 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001639 if (value < 0) return false;
1640 *index = value;
1641 return true;
1642 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001643 if (IsHeapNumber()) {
1644 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001645 uint32_t uint_value = static_cast<uint32_t>(value);
1646 if (value == static_cast<double>(uint_value)) {
1647 *index = uint_value;
1648 return true;
1649 }
1650 }
1651 return false;
1652}
1653
1654
1655bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1656 if (!this->IsJSValue()) return false;
1657
1658 JSValue* js_value = JSValue::cast(this);
1659 if (!js_value->value()->IsString()) return false;
1660
1661 String* str = String::cast(js_value->value());
1662 if (index >= (uint32_t)str->length()) return false;
1663
1664 return true;
1665}
1666
1667
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001668FixedArrayBase* FixedArrayBase::cast(Object* object) {
1669 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1670 return reinterpret_cast<FixedArrayBase*>(object);
1671}
1672
1673
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001674Object* FixedArray::get(int index) {
1675 ASSERT(index >= 0 && index < this->length());
1676 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1677}
1678
1679
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001680bool FixedArray::is_the_hole(int index) {
1681 return get(index) == GetHeap()->the_hole_value();
1682}
1683
1684
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001685void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001686 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001687 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001688 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1689 int offset = kHeaderSize + index * kPointerSize;
1690 WRITE_FIELD(this, offset, value);
1691}
1692
1693
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001694void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001695 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001696 ASSERT(index >= 0 && index < this->length());
1697 int offset = kHeaderSize + index * kPointerSize;
1698 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001699 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001700}
1701
1702
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001703inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1704 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1705}
1706
1707
1708inline double FixedDoubleArray::hole_nan_as_double() {
1709 return BitCast<double, uint64_t>(kHoleNanInt64);
1710}
1711
1712
1713inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1714 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1715 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1716 return OS::nan_value();
1717}
1718
1719
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001720double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001721 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1722 map() != HEAP->fixed_array_map());
1723 ASSERT(index >= 0 && index < this->length());
1724 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1725 ASSERT(!is_the_hole_nan(result));
1726 return result;
1727}
1728
danno@chromium.org88aa0582012-03-23 15:11:57 +00001729int64_t FixedDoubleArray::get_representation(int index) {
1730 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1731 map() != HEAP->fixed_array_map());
1732 ASSERT(index >= 0 && index < this->length());
1733 return READ_INT64_FIELD(this, kHeaderSize + index * kDoubleSize);
1734}
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001735
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001736MaybeObject* FixedDoubleArray::get(int index) {
1737 if (is_the_hole(index)) {
1738 return GetHeap()->the_hole_value();
1739 } else {
1740 return GetHeap()->NumberFromDouble(get_scalar(index));
1741 }
1742}
1743
1744
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001745void FixedDoubleArray::set(int index, double value) {
1746 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1747 map() != HEAP->fixed_array_map());
1748 int offset = kHeaderSize + index * kDoubleSize;
1749 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1750 WRITE_DOUBLE_FIELD(this, offset, value);
1751}
1752
1753
1754void FixedDoubleArray::set_the_hole(int index) {
1755 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1756 map() != HEAP->fixed_array_map());
1757 int offset = kHeaderSize + index * kDoubleSize;
1758 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1759}
1760
1761
1762bool FixedDoubleArray::is_the_hole(int index) {
1763 int offset = kHeaderSize + index * kDoubleSize;
1764 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1765}
1766
1767
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001768WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001769 Heap* heap = GetHeap();
1770 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1771 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001772 return UPDATE_WRITE_BARRIER;
1773}
1774
1775
1776void FixedArray::set(int index,
1777 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001778 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001779 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001780 ASSERT(index >= 0 && index < this->length());
1781 int offset = kHeaderSize + index * kPointerSize;
1782 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001783 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001784}
1785
1786
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001787void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1788 int index,
1789 Object* value) {
1790 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
1791 ASSERT(index >= 0 && index < array->length());
1792 int offset = kHeaderSize + index * kPointerSize;
1793 WRITE_FIELD(array, offset, value);
1794 Heap* heap = array->GetHeap();
1795 if (heap->InNewSpace(value)) {
1796 heap->RecordWrite(array->address(), offset);
1797 }
1798}
1799
1800
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001801void FixedArray::NoWriteBarrierSet(FixedArray* array,
1802 int index,
1803 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001804 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001805 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001806 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001807 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1808}
1809
1810
1811void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001812 ASSERT(map() != HEAP->fixed_cow_array_map());
1813 set_undefined(GetHeap(), index);
1814}
1815
1816
1817void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001818 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001819 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001820 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001821 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001822}
1823
1824
ager@chromium.org236ad962008-09-25 09:45:57 +00001825void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001826 set_null(GetHeap(), index);
1827}
1828
1829
1830void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001831 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001832 ASSERT(!heap->InNewSpace(heap->null_value()));
1833 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001834}
1835
1836
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001837void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001838 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001839 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001840 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1841 WRITE_FIELD(this,
1842 kHeaderSize + index * kPointerSize,
1843 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001844}
1845
1846
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001847void FixedArray::set_unchecked(int index, Smi* value) {
1848 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1849 int offset = kHeaderSize + index * kPointerSize;
1850 WRITE_FIELD(this, offset, value);
1851}
1852
1853
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001854void FixedArray::set_unchecked(Heap* heap,
1855 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001856 Object* value,
1857 WriteBarrierMode mode) {
1858 int offset = kHeaderSize + index * kPointerSize;
1859 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001860 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001861}
1862
1863
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001864void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001865 ASSERT(index >= 0 && index < this->length());
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00001866 ASSERT(!heap->InNewSpace(heap->null_value()));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001867 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001868}
1869
1870
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001871Object** FixedArray::data_start() {
1872 return HeapObject::RawField(this, kHeaderSize);
1873}
1874
1875
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001876bool DescriptorArray::IsEmpty() {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001877 ASSERT(length() >= kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001878 this == HEAP->empty_descriptor_array());
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001879 return length() < kFirstIndex;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001880}
1881
1882
1883bool DescriptorArray::MayContainTransitions() {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001884 return !IsEmpty();
danno@chromium.org40cb8782011-05-25 07:58:50 +00001885}
1886
1887
1888int DescriptorArray::bit_field3_storage() {
1889 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1890 return Smi::cast(storage)->value();
1891}
1892
1893void DescriptorArray::set_bit_field3_storage(int value) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001894 ASSERT(this->MayContainTransitions());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001895 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001896}
1897
1898
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001899void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1900 int first,
1901 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001902 Object* tmp = array->get(first);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001903 NoIncrementalWriteBarrierSet(array, first, array->get(second));
1904 NoIncrementalWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001905}
1906
1907
1908int DescriptorArray::Search(String* name) {
1909 SLOW_ASSERT(IsSortedNoDuplicates());
1910
1911 // Check for empty descriptor array.
1912 int nof = number_of_descriptors();
1913 if (nof == 0) return kNotFound;
1914
1915 // Fast case: do linear search for small arrays.
1916 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001917 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001918 return LinearSearch(EXPECT_SORTED, name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001919 }
1920
1921 // Slow case: perform binary search.
1922 return BinarySearch(name, 0, nof - 1);
1923}
1924
1925
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001926int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001927 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001928 if (number == DescriptorLookupCache::kAbsent) {
1929 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001930 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001931 }
1932 return number;
1933}
1934
1935
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001936Map* DescriptorArray::elements_transition_map() {
1937 if (!this->MayContainTransitions()) {
1938 return NULL;
1939 }
1940 Object* transition_map = get(kTransitionsIndex);
1941 if (transition_map == Smi::FromInt(0)) {
1942 return NULL;
1943 } else {
1944 return Map::cast(transition_map);
1945 }
1946}
1947
1948
1949void DescriptorArray::set_elements_transition_map(
1950 Map* transition_map, WriteBarrierMode mode) {
1951 ASSERT(this->length() > kTransitionsIndex);
1952 Heap* heap = GetHeap();
1953 WRITE_FIELD(this, kTransitionsOffset, transition_map);
1954 CONDITIONAL_WRITE_BARRIER(
1955 heap, this, kTransitionsOffset, transition_map, mode);
1956 ASSERT(DescriptorArray::cast(this));
1957}
1958
1959
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001960void DescriptorArray::ClearElementsTransition() {
1961 WRITE_FIELD(this, kTransitionsOffset, Smi::FromInt(0));
1962}
1963
1964
rossberg@chromium.org400388e2012-06-06 09:29:22 +00001965Object** DescriptorArray::GetKeySlot(int descriptor_number) {
1966 ASSERT(descriptor_number < number_of_descriptors());
1967 return HeapObject::RawField(
1968 reinterpret_cast<HeapObject*>(this),
1969 OffsetOfElementAt(ToKeyIndex(descriptor_number)));
1970}
1971
1972
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001973String* DescriptorArray::GetKey(int descriptor_number) {
1974 ASSERT(descriptor_number < number_of_descriptors());
1975 return String::cast(get(ToKeyIndex(descriptor_number)));
1976}
1977
1978
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00001979void DescriptorArray::SetKeyUnchecked(Heap* heap,
1980 int descriptor_number,
1981 String* key) {
1982 ASSERT(descriptor_number < number_of_descriptors());
1983 set_unchecked(heap,
1984 ToKeyIndex(descriptor_number),
1985 key,
1986 UPDATE_WRITE_BARRIER);
1987}
1988
1989
verwaest@chromium.org37141392012-05-31 13:27:02 +00001990Object** DescriptorArray::GetValueSlot(int descriptor_number) {
1991 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00001992 return HeapObject::RawField(
1993 reinterpret_cast<HeapObject*>(this),
1994 OffsetOfElementAt(ToValueIndex(descriptor_number)));
verwaest@chromium.org37141392012-05-31 13:27:02 +00001995}
1996
1997
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001998Object* DescriptorArray::GetValue(int descriptor_number) {
1999 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002000 return get(ToValueIndex(descriptor_number));
2001}
2002
2003
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00002004void DescriptorArray::SetNullValueUnchecked(Heap* heap, int descriptor_number) {
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002005 ASSERT(descriptor_number < number_of_descriptors());
2006 set_null_unchecked(heap, ToValueIndex(descriptor_number));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002007}
2008
2009
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00002010
2011void DescriptorArray::SetValueUnchecked(Heap* heap,
2012 int descriptor_number,
2013 Object* value) {
2014 ASSERT(descriptor_number < number_of_descriptors());
2015 set_unchecked(heap,
2016 ToValueIndex(descriptor_number),
2017 value,
2018 UPDATE_WRITE_BARRIER);
2019}
2020
2021
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002022PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002023 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002024 Object* details = get(ToDetailsIndex(descriptor_number));
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002025 return PropertyDetails(Smi::cast(details));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002026}
2027
2028
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002029void DescriptorArray::SetDetailsUnchecked(int descriptor_number, Smi* value) {
2030 ASSERT(descriptor_number < number_of_descriptors());
2031 set_unchecked(ToDetailsIndex(descriptor_number), value);
2032}
2033
2034
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002035PropertyType DescriptorArray::GetType(int descriptor_number) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002036 return GetDetails(descriptor_number).type();
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002037}
2038
2039
2040int DescriptorArray::GetFieldIndex(int descriptor_number) {
2041 return Descriptor::IndexFromValue(GetValue(descriptor_number));
2042}
2043
2044
2045JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
2046 return JSFunction::cast(GetValue(descriptor_number));
2047}
2048
2049
2050Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
2051 ASSERT(GetType(descriptor_number) == CALLBACKS);
2052 return GetValue(descriptor_number);
2053}
2054
2055
2056AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
2057 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002058 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002059 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002060}
2061
2062
2063bool DescriptorArray::IsProperty(int descriptor_number) {
ulan@chromium.org9a21ec42012-03-06 08:42:24 +00002064 Entry entry(this, descriptor_number);
2065 return IsPropertyDescriptor(&entry);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002066}
2067
2068
rossberg@chromium.org994edf62012-02-06 10:12:55 +00002069bool DescriptorArray::IsTransitionOnly(int descriptor_number) {
2070 switch (GetType(descriptor_number)) {
2071 case MAP_TRANSITION:
2072 case CONSTANT_TRANSITION:
rossberg@chromium.org994edf62012-02-06 10:12:55 +00002073 return true;
2074 case CALLBACKS: {
2075 Object* value = GetValue(descriptor_number);
2076 if (!value->IsAccessorPair()) return false;
2077 AccessorPair* accessors = AccessorPair::cast(value);
2078 return accessors->getter()->IsMap() && accessors->setter()->IsMap();
2079 }
2080 case NORMAL:
2081 case FIELD:
2082 case CONSTANT_FUNCTION:
2083 case HANDLER:
2084 case INTERCEPTOR:
rossberg@chromium.org994edf62012-02-06 10:12:55 +00002085 return false;
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00002086 case NONEXISTENT:
2087 UNREACHABLE();
2088 break;
rossberg@chromium.org994edf62012-02-06 10:12:55 +00002089 }
2090 UNREACHABLE(); // Keep the compiler happy.
2091 return false;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002092}
2093
2094
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002095void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2096 desc->Init(GetKey(descriptor_number),
2097 GetValue(descriptor_number),
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002098 GetDetails(descriptor_number));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002099}
2100
2101
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002102void DescriptorArray::Set(int descriptor_number,
2103 Descriptor* desc,
2104 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002105 // Range check.
2106 ASSERT(descriptor_number < number_of_descriptors());
2107
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002108 NoIncrementalWriteBarrierSet(this,
2109 ToKeyIndex(descriptor_number),
2110 desc->GetKey());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002111 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002112 ToValueIndex(descriptor_number),
2113 desc->GetValue());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002114 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002115 ToDetailsIndex(descriptor_number),
2116 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002117}
2118
2119
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002120void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2121 int first, int second) {
2122 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002123 NoIncrementalWriteBarrierSwap(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002124 ToValueIndex(first),
2125 ToValueIndex(second));
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002126 NoIncrementalWriteBarrierSwap(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002127 ToDetailsIndex(first),
2128 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002129}
2130
2131
2132DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
2133 : marking_(array->GetHeap()->incremental_marking()) {
2134 marking_->EnterNoMarkingScope();
2135 if (array->number_of_descriptors() > 0) {
2136 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002137 }
2138}
2139
2140
2141DescriptorArray::WhitenessWitness::~WhitenessWitness() {
2142 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002143}
2144
2145
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002146template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002147int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2148 const int kMinCapacity = 32;
2149 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2150 if (capacity < kMinCapacity) {
2151 capacity = kMinCapacity; // Guarantee min capacity.
2152 }
2153 return capacity;
2154}
2155
2156
2157template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002158int HashTable<Shape, Key>::FindEntry(Key key) {
2159 return FindEntry(GetIsolate(), key);
2160}
2161
2162
2163// Find entry for key otherwise return kNotFound.
2164template<typename Shape, typename Key>
2165int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2166 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002167 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002168 uint32_t count = 1;
2169 // EnsureCapacity will guarantee the hash table is never full.
2170 while (true) {
2171 Object* element = KeyAt(entry);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002172 // Empty entry.
2173 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2174 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002175 Shape::IsMatch(key, element)) return entry;
2176 entry = NextProbe(entry, count++, capacity);
2177 }
2178 return kNotFound;
2179}
2180
2181
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002182bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002183 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002184 if (!max_index_object->IsSmi()) return false;
2185 return 0 !=
2186 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2187}
2188
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002189uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002190 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002191 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002192 if (!max_index_object->IsSmi()) return 0;
2193 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2194 return value >> kRequiresSlowElementsTagSize;
2195}
2196
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002197void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002198 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002199}
2200
2201
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002202// ------------------------------------
2203// Cast operations
2204
2205
2206CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002207CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002208CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002209CAST_ACCESSOR(DeoptimizationInputData)
2210CAST_ACCESSOR(DeoptimizationOutputData)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002211CAST_ACCESSOR(TypeFeedbackCells)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002212CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002213CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002214CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002215CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002216CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002217CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002218CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002219CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002220CAST_ACCESSOR(String)
2221CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002222CAST_ACCESSOR(SeqAsciiString)
2223CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002224CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002225CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002226CAST_ACCESSOR(ExternalString)
2227CAST_ACCESSOR(ExternalAsciiString)
2228CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002229CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002230CAST_ACCESSOR(JSObject)
2231CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002232CAST_ACCESSOR(HeapObject)
2233CAST_ACCESSOR(HeapNumber)
2234CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002235CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002236CAST_ACCESSOR(SharedFunctionInfo)
2237CAST_ACCESSOR(Map)
2238CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002239CAST_ACCESSOR(GlobalObject)
2240CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002241CAST_ACCESSOR(JSGlobalObject)
2242CAST_ACCESSOR(JSBuiltinsObject)
2243CAST_ACCESSOR(Code)
2244CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002245CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002246CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002247CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002248CAST_ACCESSOR(JSSet)
2249CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002250CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002251CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002252CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002253CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002254CAST_ACCESSOR(ExternalArray)
2255CAST_ACCESSOR(ExternalByteArray)
2256CAST_ACCESSOR(ExternalUnsignedByteArray)
2257CAST_ACCESSOR(ExternalShortArray)
2258CAST_ACCESSOR(ExternalUnsignedShortArray)
2259CAST_ACCESSOR(ExternalIntArray)
2260CAST_ACCESSOR(ExternalUnsignedIntArray)
2261CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002262CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002263CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002264CAST_ACCESSOR(Struct)
2265
2266
2267#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2268 STRUCT_LIST(MAKE_STRUCT_CAST)
2269#undef MAKE_STRUCT_CAST
2270
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002271
2272template <typename Shape, typename Key>
2273HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002274 ASSERT(obj->IsHashTable());
2275 return reinterpret_cast<HashTable*>(obj);
2276}
2277
2278
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002279SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002280SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002281
ager@chromium.orgac091b72010-05-05 07:34:42 +00002282SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002283
2284
2285uint32_t String::hash_field() {
2286 return READ_UINT32_FIELD(this, kHashFieldOffset);
2287}
2288
2289
2290void String::set_hash_field(uint32_t value) {
2291 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002292#if V8_HOST_ARCH_64_BIT
2293 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2294#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002295}
2296
2297
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002298bool String::Equals(String* other) {
2299 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002300 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2301 return false;
2302 }
2303 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002304}
2305
2306
lrn@chromium.org303ada72010-10-27 09:33:13 +00002307MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002308 if (!StringShape(this).IsCons()) return this;
2309 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002310 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002311 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002312}
2313
2314
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002315String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002316 MaybeObject* flat = TryFlatten(pretenure);
2317 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002318 if (!flat->ToObject(&successfully_flattened)) return this;
2319 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002320}
2321
2322
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002323uint16_t String::Get(int index) {
2324 ASSERT(index >= 0 && index < length());
2325 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002326 case kSeqStringTag | kAsciiStringTag:
2327 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2328 case kSeqStringTag | kTwoByteStringTag:
2329 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2330 case kConsStringTag | kAsciiStringTag:
2331 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002332 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002333 case kExternalStringTag | kAsciiStringTag:
2334 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2335 case kExternalStringTag | kTwoByteStringTag:
2336 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002337 case kSlicedStringTag | kAsciiStringTag:
2338 case kSlicedStringTag | kTwoByteStringTag:
2339 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002340 default:
2341 break;
2342 }
2343
2344 UNREACHABLE();
2345 return 0;
2346}
2347
2348
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002349void String::Set(int index, uint16_t value) {
2350 ASSERT(index >= 0 && index < length());
2351 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002352
ager@chromium.org5ec48922009-05-05 07:25:34 +00002353 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002354 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2355 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002356}
2357
2358
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002359bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002360 if (!StringShape(this).IsCons()) return true;
2361 return ConsString::cast(this)->second()->length() == 0;
2362}
2363
2364
2365String* String::GetUnderlying() {
2366 // Giving direct access to underlying string only makes sense if the
2367 // wrapping string is already flattened.
2368 ASSERT(this->IsFlat());
2369 ASSERT(StringShape(this).IsIndirect());
2370 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2371 const int kUnderlyingOffset = SlicedString::kParentOffset;
2372 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002373}
2374
2375
ager@chromium.org7c537e22008-10-16 08:43:32 +00002376uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002377 ASSERT(index >= 0 && index < length());
2378 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2379}
2380
2381
ager@chromium.org7c537e22008-10-16 08:43:32 +00002382void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002383 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2384 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2385 static_cast<byte>(value));
2386}
2387
2388
ager@chromium.org7c537e22008-10-16 08:43:32 +00002389Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002390 return FIELD_ADDR(this, kHeaderSize);
2391}
2392
2393
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002394char* SeqAsciiString::GetChars() {
2395 return reinterpret_cast<char*>(GetCharsAddress());
2396}
2397
2398
ager@chromium.org7c537e22008-10-16 08:43:32 +00002399Address SeqTwoByteString::GetCharsAddress() {
2400 return FIELD_ADDR(this, kHeaderSize);
2401}
2402
2403
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002404uc16* SeqTwoByteString::GetChars() {
2405 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2406}
2407
2408
ager@chromium.org7c537e22008-10-16 08:43:32 +00002409uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002410 ASSERT(index >= 0 && index < length());
2411 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2412}
2413
2414
ager@chromium.org7c537e22008-10-16 08:43:32 +00002415void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002416 ASSERT(index >= 0 && index < length());
2417 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2418}
2419
2420
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002421int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002422 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002423}
2424
2425
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002426int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002427 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002428}
2429
2430
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002431String* SlicedString::parent() {
2432 return String::cast(READ_FIELD(this, kParentOffset));
2433}
2434
2435
2436void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002437 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002438 WRITE_FIELD(this, kParentOffset, parent);
2439}
2440
2441
2442SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2443
2444
ager@chromium.org870a0b62008-11-04 11:43:05 +00002445String* ConsString::first() {
2446 return String::cast(READ_FIELD(this, kFirstOffset));
2447}
2448
2449
2450Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002451 return READ_FIELD(this, kFirstOffset);
2452}
2453
2454
ager@chromium.org870a0b62008-11-04 11:43:05 +00002455void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002456 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002457 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002458}
2459
2460
ager@chromium.org870a0b62008-11-04 11:43:05 +00002461String* ConsString::second() {
2462 return String::cast(READ_FIELD(this, kSecondOffset));
2463}
2464
2465
2466Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002467 return READ_FIELD(this, kSecondOffset);
2468}
2469
2470
ager@chromium.org870a0b62008-11-04 11:43:05 +00002471void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002472 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002473 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002474}
2475
2476
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002477bool ExternalString::is_short() {
2478 InstanceType type = map()->instance_type();
2479 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002480}
2481
2482
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002483const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002484 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2485}
2486
2487
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002488void ExternalAsciiString::update_data_cache() {
2489 if (is_short()) return;
2490 const char** data_field =
2491 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2492 *data_field = resource()->data();
2493}
2494
2495
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002496void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002497 const ExternalAsciiString::Resource* resource) {
2498 *reinterpret_cast<const Resource**>(
2499 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002500 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002501}
2502
2503
2504const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002505 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002506}
2507
2508
2509uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2510 ASSERT(index >= 0 && index < length());
2511 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002512}
2513
2514
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002515const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002516 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2517}
2518
2519
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002520void ExternalTwoByteString::update_data_cache() {
2521 if (is_short()) return;
2522 const uint16_t** data_field =
2523 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2524 *data_field = resource()->data();
2525}
2526
2527
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002528void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002529 const ExternalTwoByteString::Resource* resource) {
2530 *reinterpret_cast<const Resource**>(
2531 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002532 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002533}
2534
2535
2536const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002537 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002538}
2539
2540
2541uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2542 ASSERT(index >= 0 && index < length());
2543 return GetChars()[index];
2544}
2545
2546
2547const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2548 unsigned start) {
2549 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002550}
2551
2552
ager@chromium.orgac091b72010-05-05 07:34:42 +00002553void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002554 set_finger_index(kEntriesIndex);
2555 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002556}
2557
2558
2559void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002560 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002561 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002562 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002563 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002564 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002565 MakeZeroSize();
2566}
2567
2568
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002569int JSFunctionResultCache::size() {
2570 return Smi::cast(get(kCacheSizeIndex))->value();
2571}
2572
2573
2574void JSFunctionResultCache::set_size(int size) {
2575 set(kCacheSizeIndex, Smi::FromInt(size));
2576}
2577
2578
2579int JSFunctionResultCache::finger_index() {
2580 return Smi::cast(get(kFingerIndex))->value();
2581}
2582
2583
2584void JSFunctionResultCache::set_finger_index(int finger_index) {
2585 set(kFingerIndex, Smi::FromInt(finger_index));
2586}
2587
2588
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002589byte ByteArray::get(int index) {
2590 ASSERT(index >= 0 && index < this->length());
2591 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2592}
2593
2594
2595void ByteArray::set(int index, byte value) {
2596 ASSERT(index >= 0 && index < this->length());
2597 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2598}
2599
2600
2601int ByteArray::get_int(int index) {
2602 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2603 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2604}
2605
2606
2607ByteArray* ByteArray::FromDataStartAddress(Address address) {
2608 ASSERT_TAG_ALIGNED(address);
2609 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2610}
2611
2612
2613Address ByteArray::GetDataStartAddress() {
2614 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2615}
2616
2617
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002618uint8_t* ExternalPixelArray::external_pixel_pointer() {
2619 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002620}
2621
2622
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002623uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002624 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002625 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002626 return ptr[index];
2627}
2628
2629
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002630MaybeObject* ExternalPixelArray::get(int index) {
2631 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2632}
2633
2634
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002635void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002636 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002637 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002638 ptr[index] = value;
2639}
2640
2641
ager@chromium.org3811b432009-10-28 14:53:37 +00002642void* ExternalArray::external_pointer() {
2643 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2644 return reinterpret_cast<void*>(ptr);
2645}
2646
2647
2648void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2649 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2650 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2651}
2652
2653
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002654int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002655 ASSERT((index >= 0) && (index < this->length()));
2656 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2657 return ptr[index];
2658}
2659
2660
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002661MaybeObject* ExternalByteArray::get(int index) {
2662 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2663}
2664
2665
ager@chromium.org3811b432009-10-28 14:53:37 +00002666void ExternalByteArray::set(int index, int8_t value) {
2667 ASSERT((index >= 0) && (index < this->length()));
2668 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2669 ptr[index] = value;
2670}
2671
2672
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002673uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002674 ASSERT((index >= 0) && (index < this->length()));
2675 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2676 return ptr[index];
2677}
2678
2679
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002680MaybeObject* ExternalUnsignedByteArray::get(int index) {
2681 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2682}
2683
2684
ager@chromium.org3811b432009-10-28 14:53:37 +00002685void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2686 ASSERT((index >= 0) && (index < this->length()));
2687 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2688 ptr[index] = value;
2689}
2690
2691
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002692int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002693 ASSERT((index >= 0) && (index < this->length()));
2694 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2695 return ptr[index];
2696}
2697
2698
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002699MaybeObject* ExternalShortArray::get(int index) {
2700 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2701}
2702
2703
ager@chromium.org3811b432009-10-28 14:53:37 +00002704void ExternalShortArray::set(int index, int16_t value) {
2705 ASSERT((index >= 0) && (index < this->length()));
2706 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2707 ptr[index] = value;
2708}
2709
2710
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002711uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002712 ASSERT((index >= 0) && (index < this->length()));
2713 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2714 return ptr[index];
2715}
2716
2717
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002718MaybeObject* ExternalUnsignedShortArray::get(int index) {
2719 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2720}
2721
2722
ager@chromium.org3811b432009-10-28 14:53:37 +00002723void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2724 ASSERT((index >= 0) && (index < this->length()));
2725 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2726 ptr[index] = value;
2727}
2728
2729
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002730int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002731 ASSERT((index >= 0) && (index < this->length()));
2732 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2733 return ptr[index];
2734}
2735
2736
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002737MaybeObject* ExternalIntArray::get(int index) {
2738 return GetHeap()->NumberFromInt32(get_scalar(index));
2739}
2740
2741
ager@chromium.org3811b432009-10-28 14:53:37 +00002742void ExternalIntArray::set(int index, int32_t value) {
2743 ASSERT((index >= 0) && (index < this->length()));
2744 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2745 ptr[index] = value;
2746}
2747
2748
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002749uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002750 ASSERT((index >= 0) && (index < this->length()));
2751 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2752 return ptr[index];
2753}
2754
2755
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002756MaybeObject* ExternalUnsignedIntArray::get(int index) {
2757 return GetHeap()->NumberFromUint32(get_scalar(index));
2758}
2759
2760
ager@chromium.org3811b432009-10-28 14:53:37 +00002761void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2762 ASSERT((index >= 0) && (index < this->length()));
2763 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2764 ptr[index] = value;
2765}
2766
2767
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002768float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002769 ASSERT((index >= 0) && (index < this->length()));
2770 float* ptr = static_cast<float*>(external_pointer());
2771 return ptr[index];
2772}
2773
2774
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002775MaybeObject* ExternalFloatArray::get(int index) {
2776 return GetHeap()->NumberFromDouble(get_scalar(index));
2777}
2778
2779
ager@chromium.org3811b432009-10-28 14:53:37 +00002780void ExternalFloatArray::set(int index, float value) {
2781 ASSERT((index >= 0) && (index < this->length()));
2782 float* ptr = static_cast<float*>(external_pointer());
2783 ptr[index] = value;
2784}
2785
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002786
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002787double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002788 ASSERT((index >= 0) && (index < this->length()));
2789 double* ptr = static_cast<double*>(external_pointer());
2790 return ptr[index];
2791}
2792
2793
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002794MaybeObject* ExternalDoubleArray::get(int index) {
2795 return GetHeap()->NumberFromDouble(get_scalar(index));
2796}
2797
2798
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002799void ExternalDoubleArray::set(int index, double value) {
2800 ASSERT((index >= 0) && (index < this->length()));
2801 double* ptr = static_cast<double*>(external_pointer());
2802 ptr[index] = value;
2803}
2804
2805
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002806int Map::visitor_id() {
2807 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2808}
2809
2810
2811void Map::set_visitor_id(int id) {
2812 ASSERT(0 <= id && id < 256);
2813 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2814}
2815
ager@chromium.org3811b432009-10-28 14:53:37 +00002816
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002817int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002818 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2819}
2820
2821
2822int Map::inobject_properties() {
2823 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002824}
2825
2826
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002827int Map::pre_allocated_property_fields() {
2828 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2829}
2830
2831
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002832int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002833 int instance_size = map->instance_size();
2834 if (instance_size != kVariableSizeSentinel) return instance_size;
2835 // We can ignore the "symbol" bit becase it is only set for symbols
2836 // and implies a string type.
2837 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002838 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002839 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002840 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002841 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002842 if (instance_type == ASCII_STRING_TYPE) {
2843 return SeqAsciiString::SizeFor(
2844 reinterpret_cast<SeqAsciiString*>(this)->length());
2845 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002846 if (instance_type == BYTE_ARRAY_TYPE) {
2847 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2848 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002849 if (instance_type == FREE_SPACE_TYPE) {
2850 return reinterpret_cast<FreeSpace*>(this)->size();
2851 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002852 if (instance_type == STRING_TYPE) {
2853 return SeqTwoByteString::SizeFor(
2854 reinterpret_cast<SeqTwoByteString*>(this)->length());
2855 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002856 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2857 return FixedDoubleArray::SizeFor(
2858 reinterpret_cast<FixedDoubleArray*>(this)->length());
2859 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002860 ASSERT(instance_type == CODE_TYPE);
2861 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002862}
2863
2864
2865void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002866 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002867 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002868 ASSERT(0 <= value && value < 256);
2869 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2870}
2871
2872
ager@chromium.org7c537e22008-10-16 08:43:32 +00002873void Map::set_inobject_properties(int value) {
2874 ASSERT(0 <= value && value < 256);
2875 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2876}
2877
2878
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002879void Map::set_pre_allocated_property_fields(int value) {
2880 ASSERT(0 <= value && value < 256);
2881 WRITE_BYTE_FIELD(this,
2882 kPreAllocatedPropertyFieldsOffset,
2883 static_cast<byte>(value));
2884}
2885
2886
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002887InstanceType Map::instance_type() {
2888 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2889}
2890
2891
2892void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002893 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2894}
2895
2896
2897int Map::unused_property_fields() {
2898 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2899}
2900
2901
2902void Map::set_unused_property_fields(int value) {
2903 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2904}
2905
2906
2907byte Map::bit_field() {
2908 return READ_BYTE_FIELD(this, kBitFieldOffset);
2909}
2910
2911
2912void Map::set_bit_field(byte value) {
2913 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2914}
2915
2916
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002917byte Map::bit_field2() {
2918 return READ_BYTE_FIELD(this, kBitField2Offset);
2919}
2920
2921
2922void Map::set_bit_field2(byte value) {
2923 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2924}
2925
2926
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002927void Map::set_non_instance_prototype(bool value) {
2928 if (value) {
2929 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2930 } else {
2931 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2932 }
2933}
2934
2935
2936bool Map::has_non_instance_prototype() {
2937 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2938}
2939
2940
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002941void Map::set_function_with_prototype(bool value) {
2942 if (value) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002943 set_bit_field3(bit_field3() | (1 << kFunctionWithPrototype));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002944 } else {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002945 set_bit_field3(bit_field3() & ~(1 << kFunctionWithPrototype));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002946 }
2947}
2948
2949
2950bool Map::function_with_prototype() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002951 return ((1 << kFunctionWithPrototype) & bit_field3()) != 0;
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002952}
2953
2954
ager@chromium.org870a0b62008-11-04 11:43:05 +00002955void Map::set_is_access_check_needed(bool access_check_needed) {
2956 if (access_check_needed) {
2957 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2958 } else {
2959 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2960 }
2961}
2962
2963
2964bool Map::is_access_check_needed() {
2965 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2966}
2967
2968
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002969void Map::set_is_extensible(bool value) {
2970 if (value) {
2971 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2972 } else {
2973 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2974 }
2975}
2976
2977bool Map::is_extensible() {
2978 return ((1 << kIsExtensible) & bit_field2()) != 0;
2979}
2980
2981
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002982void Map::set_attached_to_shared_function_info(bool value) {
2983 if (value) {
2984 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2985 } else {
2986 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2987 }
2988}
2989
2990bool Map::attached_to_shared_function_info() {
2991 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2992}
2993
2994
2995void Map::set_is_shared(bool value) {
2996 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002997 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002998 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002999 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003000 }
3001}
3002
3003bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003004 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003005}
3006
3007
3008JSFunction* Map::unchecked_constructor() {
3009 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
3010}
3011
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003012
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003013Code::Flags Code::flags() {
3014 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
3015}
3016
3017
3018void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003019 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003020 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003021 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
3022 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003023 ExtractArgumentsCountFromFlags(flags) >= 0);
3024 WRITE_INT_FIELD(this, kFlagsOffset, flags);
3025}
3026
3027
3028Code::Kind Code::kind() {
3029 return ExtractKindFromFlags(flags());
3030}
3031
3032
kasper.lund7276f142008-07-30 08:49:36 +00003033InlineCacheState Code::ic_state() {
3034 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003035 // Only allow uninitialized or debugger states for non-IC code
3036 // objects. This is used in the debugger to determine whether or not
3037 // a call to code object has been replaced with a debug break call.
3038 ASSERT(is_inline_cache_stub() ||
3039 result == UNINITIALIZED ||
3040 result == DEBUG_BREAK ||
3041 result == DEBUG_PREPARE_STEP_IN);
3042 return result;
3043}
3044
3045
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003046Code::ExtraICState Code::extra_ic_state() {
3047 ASSERT(is_inline_cache_stub());
3048 return ExtractExtraICStateFromFlags(flags());
3049}
3050
3051
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003052Code::StubType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003053 return ExtractTypeFromFlags(flags());
3054}
3055
3056
3057int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003058 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003059 return ExtractArgumentsCountFromFlags(flags());
3060}
3061
3062
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003063int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003064 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003065 kind() == UNARY_OP_IC ||
3066 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003067 kind() == COMPARE_IC ||
3068 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003069 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00003070}
3071
3072
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003073void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003074 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003075 kind() == UNARY_OP_IC ||
3076 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003077 kind() == COMPARE_IC ||
3078 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00003079 ASSERT(0 <= major && major < 256);
3080 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003081}
3082
3083
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003084bool Code::is_pregenerated() {
3085 return kind() == STUB && IsPregeneratedField::decode(flags());
3086}
3087
3088
3089void Code::set_is_pregenerated(bool value) {
3090 ASSERT(kind() == STUB);
3091 Flags f = flags();
3092 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3093 set_flags(f);
3094}
3095
3096
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003097bool Code::optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003098 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003099 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3100}
3101
3102
3103void Code::set_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003104 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003105 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3106}
3107
3108
3109bool Code::has_deoptimization_support() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003110 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003111 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3112 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003113}
3114
3115
3116void Code::set_has_deoptimization_support(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003117 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003118 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3119 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3120 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3121}
3122
3123
3124bool Code::has_debug_break_slots() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003125 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003126 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3127 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3128}
3129
3130
3131void Code::set_has_debug_break_slots(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003132 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003133 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3134 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3135 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003136}
3137
3138
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003139bool Code::is_compiled_optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003140 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003141 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3142 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3143}
3144
3145
3146void Code::set_compiled_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003147 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003148 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3149 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3150 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3151}
3152
3153
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003154int Code::allow_osr_at_loop_nesting_level() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003155 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003156 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3157}
3158
3159
3160void Code::set_allow_osr_at_loop_nesting_level(int level) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003161 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003162 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3163 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3164}
3165
3166
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003167int Code::profiler_ticks() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003168 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003169 return READ_BYTE_FIELD(this, kProfilerTicksOffset);
3170}
3171
3172
3173void Code::set_profiler_ticks(int ticks) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003174 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003175 ASSERT(ticks < 256);
3176 WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
3177}
3178
3179
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003180unsigned Code::stack_slots() {
3181 ASSERT(kind() == OPTIMIZED_FUNCTION);
3182 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3183}
3184
3185
3186void Code::set_stack_slots(unsigned slots) {
3187 ASSERT(kind() == OPTIMIZED_FUNCTION);
3188 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3189}
3190
3191
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003192unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003193 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003194 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003195}
3196
3197
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003198void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003199 ASSERT(kind() == OPTIMIZED_FUNCTION);
3200 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003201 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003202}
3203
3204
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003205unsigned Code::stack_check_table_offset() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003206 ASSERT_EQ(FUNCTION, kind());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003207 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003208}
3209
3210
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003211void Code::set_stack_check_table_offset(unsigned offset) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003212 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003213 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003214 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003215}
3216
3217
3218CheckType Code::check_type() {
3219 ASSERT(is_call_stub() || is_keyed_call_stub());
3220 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3221 return static_cast<CheckType>(type);
3222}
3223
3224
3225void Code::set_check_type(CheckType value) {
3226 ASSERT(is_call_stub() || is_keyed_call_stub());
3227 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3228}
3229
3230
danno@chromium.org40cb8782011-05-25 07:58:50 +00003231byte Code::unary_op_type() {
3232 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003233 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3234}
3235
3236
danno@chromium.org40cb8782011-05-25 07:58:50 +00003237void Code::set_unary_op_type(byte value) {
3238 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003239 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3240}
3241
3242
danno@chromium.org40cb8782011-05-25 07:58:50 +00003243byte Code::binary_op_type() {
3244 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003245 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3246}
3247
3248
danno@chromium.org40cb8782011-05-25 07:58:50 +00003249void Code::set_binary_op_type(byte value) {
3250 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003251 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3252}
3253
3254
danno@chromium.org40cb8782011-05-25 07:58:50 +00003255byte Code::binary_op_result_type() {
3256 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003257 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3258}
3259
3260
danno@chromium.org40cb8782011-05-25 07:58:50 +00003261void Code::set_binary_op_result_type(byte value) {
3262 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003263 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3264}
3265
3266
3267byte Code::compare_state() {
3268 ASSERT(is_compare_ic_stub());
3269 return READ_BYTE_FIELD(this, kCompareStateOffset);
3270}
3271
3272
3273void Code::set_compare_state(byte value) {
3274 ASSERT(is_compare_ic_stub());
3275 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3276}
3277
3278
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003279byte Code::compare_operation() {
3280 ASSERT(is_compare_ic_stub());
3281 return READ_BYTE_FIELD(this, kCompareOperationOffset);
3282}
3283
3284
3285void Code::set_compare_operation(byte value) {
3286 ASSERT(is_compare_ic_stub());
3287 WRITE_BYTE_FIELD(this, kCompareOperationOffset, value);
3288}
3289
3290
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003291byte Code::to_boolean_state() {
3292 ASSERT(is_to_boolean_ic_stub());
3293 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3294}
3295
3296
3297void Code::set_to_boolean_state(byte value) {
3298 ASSERT(is_to_boolean_ic_stub());
3299 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3300}
3301
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003302
3303bool Code::has_function_cache() {
3304 ASSERT(kind() == STUB);
3305 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3306}
3307
3308
3309void Code::set_has_function_cache(bool flag) {
3310 ASSERT(kind() == STUB);
3311 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3312}
3313
3314
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003315bool Code::is_inline_cache_stub() {
3316 Kind kind = this->kind();
3317 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3318}
3319
3320
3321Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003322 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003323 ExtraICState extra_ic_state,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003324 StubType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003325 int argc,
3326 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003327 // Extra IC state is only allowed for call IC stubs or for store IC
3328 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003329 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003330 kind == CALL_IC ||
3331 kind == STORE_IC ||
3332 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003333 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003334 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003335 | ICStateField::encode(ic_state)
3336 | TypeField::encode(type)
3337 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003338 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003339 | CacheHolderField::encode(holder);
3340 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003341}
3342
3343
3344Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003345 StubType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003346 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003347 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003348 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003349 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003350}
3351
3352
3353Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003354 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003355}
3356
3357
kasper.lund7276f142008-07-30 08:49:36 +00003358InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003359 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003360}
3361
3362
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003363Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003364 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003365}
3366
3367
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003368Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003369 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003370}
3371
3372
3373int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003374 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003375}
3376
3377
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003378InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003379 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003380}
3381
3382
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003383Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003384 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003385 return static_cast<Flags>(bits);
3386}
3387
3388
ager@chromium.org8bb60582008-12-11 12:02:20 +00003389Code* Code::GetCodeFromTargetAddress(Address address) {
3390 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3391 // GetCodeFromTargetAddress might be called when marking objects during mark
3392 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3393 // Code::cast. Code::cast does not work when the object's map is
3394 // marked.
3395 Code* result = reinterpret_cast<Code*>(code);
3396 return result;
3397}
3398
3399
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003400Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3401 return HeapObject::
3402 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3403}
3404
3405
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003406Object* Map::prototype() {
3407 return READ_FIELD(this, kPrototypeOffset);
3408}
3409
3410
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003411void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003412 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003413 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003414 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003415}
3416
3417
danno@chromium.org40cb8782011-05-25 07:58:50 +00003418DescriptorArray* Map::instance_descriptors() {
3419 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3420 if (object->IsSmi()) {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003421 return GetHeap()->empty_descriptor_array();
danno@chromium.org40cb8782011-05-25 07:58:50 +00003422 } else {
3423 return DescriptorArray::cast(object);
3424 }
3425}
3426
3427
3428void Map::init_instance_descriptors() {
3429 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3430}
3431
3432
3433void Map::clear_instance_descriptors() {
3434 Object* object = READ_FIELD(this,
3435 kInstanceDescriptorsOrBitField3Offset);
3436 if (!object->IsSmi()) {
yangguo@chromium.org5f0b8ea2012-05-16 12:37:04 +00003437#ifdef DEBUG
3438 ZapInstanceDescriptors();
3439#endif
danno@chromium.org40cb8782011-05-25 07:58:50 +00003440 WRITE_FIELD(
3441 this,
3442 kInstanceDescriptorsOrBitField3Offset,
3443 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3444 }
3445}
3446
3447
3448void Map::set_instance_descriptors(DescriptorArray* value,
3449 WriteBarrierMode mode) {
3450 Object* object = READ_FIELD(this,
3451 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003452 Heap* heap = GetHeap();
3453 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003454 clear_instance_descriptors();
3455 return;
3456 } else {
3457 if (object->IsSmi()) {
3458 value->set_bit_field3_storage(Smi::cast(object)->value());
3459 } else {
3460 value->set_bit_field3_storage(
3461 DescriptorArray::cast(object)->bit_field3_storage());
3462 }
3463 }
3464 ASSERT(!is_shared());
yangguo@chromium.org5f0b8ea2012-05-16 12:37:04 +00003465#ifdef DEBUG
3466 if (value != instance_descriptors()) {
3467 ZapInstanceDescriptors();
3468 }
3469#endif
danno@chromium.org40cb8782011-05-25 07:58:50 +00003470 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003471 CONDITIONAL_WRITE_BARRIER(
3472 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003473}
3474
3475
3476int Map::bit_field3() {
3477 Object* object = READ_FIELD(this,
3478 kInstanceDescriptorsOrBitField3Offset);
3479 if (object->IsSmi()) {
3480 return Smi::cast(object)->value();
3481 } else {
3482 return DescriptorArray::cast(object)->bit_field3_storage();
3483 }
3484}
3485
3486
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003487void Map::ClearDescriptorArray() {
3488 int bitfield3 = bit_field3();
3489#ifdef DEBUG
3490 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3491 if (!object->IsSmi()) {
3492 ZapInstanceDescriptors();
3493 }
3494#endif
3495 WRITE_FIELD(this,
3496 kInstanceDescriptorsOrBitField3Offset,
3497 Smi::FromInt(bitfield3));
3498}
3499
3500
danno@chromium.org40cb8782011-05-25 07:58:50 +00003501void Map::set_bit_field3(int value) {
3502 ASSERT(Smi::IsValid(value));
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003503 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003504 if (object->IsSmi()) {
3505 WRITE_FIELD(this,
3506 kInstanceDescriptorsOrBitField3Offset,
3507 Smi::FromInt(value));
3508 } else {
3509 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3510 }
3511}
3512
3513
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003514Object* Map::GetBackPointer() {
3515 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3516 if (object->IsFixedArray()) {
3517 return FixedArray::cast(object)->get(kProtoTransitionBackPointerOffset);
3518 } else {
3519 return object;
3520 }
3521}
3522
3523
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003524Map* Map::elements_transition_map() {
3525 return instance_descriptors()->elements_transition_map();
3526}
3527
3528
3529void Map::set_elements_transition_map(Map* transitioned_map) {
3530 return instance_descriptors()->set_elements_transition_map(transitioned_map);
3531}
3532
3533
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003534void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
3535 Heap* heap = GetHeap();
3536 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
3537 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
3538 (value->IsMap() && GetBackPointer()->IsUndefined()));
3539 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3540 if (object->IsFixedArray()) {
3541 FixedArray::cast(object)->set(
3542 kProtoTransitionBackPointerOffset, value, mode);
3543 } else {
3544 WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
3545 CONDITIONAL_WRITE_BARRIER(
3546 heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
3547 }
3548}
3549
3550
3551FixedArray* Map::prototype_transitions() {
3552 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3553 if (object->IsFixedArray()) {
3554 return FixedArray::cast(object);
3555 } else {
3556 return GetHeap()->empty_fixed_array();
3557 }
3558}
3559
3560
3561void Map::set_prototype_transitions(FixedArray* value, WriteBarrierMode mode) {
3562 Heap* heap = GetHeap();
3563 ASSERT(value != heap->empty_fixed_array());
3564 value->set(kProtoTransitionBackPointerOffset, GetBackPointer());
yangguo@chromium.org5f0b8ea2012-05-16 12:37:04 +00003565#ifdef DEBUG
3566 if (value != prototype_transitions()) {
3567 ZapPrototypeTransitions();
3568 }
3569#endif
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003570 WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
3571 CONDITIONAL_WRITE_BARRIER(
3572 heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
3573}
3574
3575
3576void Map::init_prototype_transitions(Object* undefined) {
3577 ASSERT(undefined->IsUndefined());
3578 WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, undefined);
3579}
3580
3581
3582HeapObject* Map::unchecked_prototype_transitions() {
3583 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3584 return reinterpret_cast<HeapObject*>(object);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003585}
3586
3587
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003588ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003589ACCESSORS(Map, constructor, Object, kConstructorOffset)
3590
3591ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003592ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003593ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003594
3595ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3596ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003597ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003598
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003599ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003600
3601ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3602ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3603ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3604ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003605ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003606ACCESSORS(AccessorInfo, expected_receiver_type, Object,
3607 kExpectedReceiverTypeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003608
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003609ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3610ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3611
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003612ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3613ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3614ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3615
3616ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3617ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3618ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3619ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3620ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3621ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3622
3623ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3624ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3625
3626ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3627ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3628
3629ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3630ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003631ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3632 kPropertyAccessorsOffset)
3633ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3634 kPrototypeTemplateOffset)
3635ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3636ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3637 kNamedPropertyHandlerOffset)
3638ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3639 kIndexedPropertyHandlerOffset)
3640ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3641 kInstanceTemplateOffset)
3642ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3643ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003644ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3645 kInstanceCallHandlerOffset)
3646ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3647 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003648ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003649
3650ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003651ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3652 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003653
3654ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3655ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3656
3657ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3658
3659ACCESSORS(Script, source, Object, kSourceOffset)
3660ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003661ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003662ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
3663ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003664ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003665ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003666ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003667ACCESSORS_TO_SMI(Script, type, kTypeOffset)
3668ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
3669ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003670ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003671ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003672ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
3673 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003674
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003675#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003676ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3677ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3678ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3679ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3680
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003681ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
3682ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
3683ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003684ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003685#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003686
3687ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003688ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
3689 kOptimizedCodeMapOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003690ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3691ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003692ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3693 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003694ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003695ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3696ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003697ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003698ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3699 kThisPropertyAssignmentsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003700SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003701
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00003702
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003703BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3704 kHiddenPrototypeBit)
3705BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3706BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3707 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003708BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3709 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003710BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3711 kIsExpressionBit)
3712BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3713 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003714BOOL_GETTER(SharedFunctionInfo,
3715 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003716 has_only_simple_this_property_assignments,
3717 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003718BOOL_ACCESSORS(SharedFunctionInfo,
3719 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003720 allows_lazy_compilation,
3721 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003722BOOL_ACCESSORS(SharedFunctionInfo,
3723 compiler_hints,
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003724 allows_lazy_compilation_without_context,
3725 kAllowLazyCompilationWithoutContext)
3726BOOL_ACCESSORS(SharedFunctionInfo,
3727 compiler_hints,
whesse@chromium.org7b260152011-06-20 15:33:18 +00003728 uses_arguments,
3729 kUsesArguments)
3730BOOL_ACCESSORS(SharedFunctionInfo,
3731 compiler_hints,
3732 has_duplicate_parameters,
3733 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003734
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003735
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003736#if V8_HOST_ARCH_32_BIT
3737SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3738SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003739 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003740SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003741 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003742SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3743SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003744 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003745SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3746SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003747 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003748SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003749 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003750SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003751 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003752SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003753SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
3754SMI_ACCESSORS(SharedFunctionInfo,
3755 stress_deopt_counter,
3756 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003757#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003758
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003759#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003760 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003761 int holder::name() { \
3762 int value = READ_INT_FIELD(this, offset); \
3763 ASSERT(kHeapObjectTag == 1); \
3764 ASSERT((value & kHeapObjectTag) == 0); \
3765 return value >> 1; \
3766 } \
3767 void holder::set_##name(int value) { \
3768 ASSERT(kHeapObjectTag == 1); \
3769 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3770 (value & 0xC0000000) == 0x000000000); \
3771 WRITE_INT_FIELD(this, \
3772 offset, \
3773 (value << 1) & ~kHeapObjectTag); \
3774 }
3775
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003776#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3777 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003778 INT_ACCESSORS(holder, name, offset)
3779
3780
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003781PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003782PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3783 formal_parameter_count,
3784 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003785
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003786PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3787 expected_nof_properties,
3788 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003789PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3790
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003791PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3792PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3793 start_position_and_type,
3794 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003795
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003796PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3797 function_token_position,
3798 kFunctionTokenPositionOffset)
3799PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3800 compiler_hints,
3801 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003802
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003803PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3804 this_property_assignments_count,
3805 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003806PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003807
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003808PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, counters, kCountersOffset)
3809PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3810 stress_deopt_counter,
3811 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003812#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003813
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003814
3815int SharedFunctionInfo::construction_count() {
3816 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3817}
3818
3819
3820void SharedFunctionInfo::set_construction_count(int value) {
3821 ASSERT(0 <= value && value < 256);
3822 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3823}
3824
3825
whesse@chromium.org7b260152011-06-20 15:33:18 +00003826BOOL_ACCESSORS(SharedFunctionInfo,
3827 compiler_hints,
3828 live_objects_may_exist,
3829 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003830
3831
3832bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003833 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003834}
3835
3836
whesse@chromium.org7b260152011-06-20 15:33:18 +00003837BOOL_GETTER(SharedFunctionInfo,
3838 compiler_hints,
3839 optimization_disabled,
3840 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003841
3842
3843void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3844 set_compiler_hints(BooleanBit::set(compiler_hints(),
3845 kOptimizationDisabled,
3846 disable));
3847 // If disabling optimizations we reflect that in the code object so
3848 // it will not be counted as optimizable code.
3849 if ((code()->kind() == Code::FUNCTION) && disable) {
3850 code()->set_optimizable(false);
3851 }
3852}
3853
3854
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003855int SharedFunctionInfo::profiler_ticks() {
3856 if (code()->kind() != Code::FUNCTION) return 0;
3857 return code()->profiler_ticks();
3858}
3859
3860
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003861LanguageMode SharedFunctionInfo::language_mode() {
3862 int hints = compiler_hints();
3863 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3864 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3865 return EXTENDED_MODE;
3866 }
3867 return BooleanBit::get(hints, kStrictModeFunction)
3868 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003869}
3870
3871
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003872void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3873 // We only allow language mode transitions that go set the same language mode
3874 // again or go up in the chain:
3875 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3876 ASSERT(this->language_mode() == CLASSIC_MODE ||
3877 this->language_mode() == language_mode ||
3878 language_mode == EXTENDED_MODE);
3879 int hints = compiler_hints();
3880 hints = BooleanBit::set(
3881 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3882 hints = BooleanBit::set(
3883 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3884 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003885}
3886
3887
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003888bool SharedFunctionInfo::is_classic_mode() {
3889 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3890}
3891
3892BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3893 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003894BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3895BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3896 name_should_print_as_anonymous,
3897 kNameShouldPrintAsAnonymous)
3898BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3899BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00003900BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
3901BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
3902 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003903BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003904
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00003905void SharedFunctionInfo::BeforeVisitingPointers() {
3906 if (IsInobjectSlackTrackingInProgress()) DetachInitialMap();
3907
3908 // Flush optimized code map on major GC.
3909 // Note: we may experiment with rebuilding it or retaining entries
3910 // which should survive as we iterate through optimized functions
3911 // anyway.
3912 set_optimized_code_map(Smi::FromInt(0));
3913}
3914
3915
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003916ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3917ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3918
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003919ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3920
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003921bool Script::HasValidSource() {
3922 Object* src = this->source();
3923 if (!src->IsString()) return true;
3924 String* src_str = String::cast(src);
3925 if (!StringShape(src_str).IsExternal()) return true;
3926 if (src_str->IsAsciiRepresentation()) {
3927 return ExternalAsciiString::cast(src)->resource() != NULL;
3928 } else if (src_str->IsTwoByteRepresentation()) {
3929 return ExternalTwoByteString::cast(src)->resource() != NULL;
3930 }
3931 return true;
3932}
3933
3934
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003935void SharedFunctionInfo::DontAdaptArguments() {
3936 ASSERT(code()->kind() == Code::BUILTIN);
3937 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3938}
3939
3940
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003941int SharedFunctionInfo::start_position() {
3942 return start_position_and_type() >> kStartPositionShift;
3943}
3944
3945
3946void SharedFunctionInfo::set_start_position(int start_position) {
3947 set_start_position_and_type((start_position << kStartPositionShift)
3948 | (start_position_and_type() & ~kStartPositionMask));
3949}
3950
3951
3952Code* SharedFunctionInfo::code() {
3953 return Code::cast(READ_FIELD(this, kCodeOffset));
3954}
3955
3956
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003957Code* SharedFunctionInfo::unchecked_code() {
3958 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3959}
3960
3961
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003962void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003963 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003964 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003965}
3966
3967
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003968ScopeInfo* SharedFunctionInfo::scope_info() {
3969 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003970}
3971
3972
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003973void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003974 WriteBarrierMode mode) {
3975 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003976 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3977 this,
3978 kScopeInfoOffset,
3979 reinterpret_cast<Object*>(value),
3980 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003981}
3982
3983
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003984bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003985 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003986 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003987}
3988
3989
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003990bool SharedFunctionInfo::IsApiFunction() {
3991 return function_data()->IsFunctionTemplateInfo();
3992}
3993
3994
3995FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3996 ASSERT(IsApiFunction());
3997 return FunctionTemplateInfo::cast(function_data());
3998}
3999
4000
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004001bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00004002 return function_data()->IsSmi();
4003}
4004
4005
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004006BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
4007 ASSERT(HasBuiltinFunctionId());
4008 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004009}
4010
4011
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004012int SharedFunctionInfo::code_age() {
4013 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
4014}
4015
4016
4017void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00004018 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
4019 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004020}
4021
4022
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004023int SharedFunctionInfo::ic_age() {
4024 return ICAgeBits::decode(counters());
4025}
4026
4027
4028void SharedFunctionInfo::set_ic_age(int ic_age) {
4029 set_counters(ICAgeBits::update(counters(), ic_age));
4030}
4031
4032
4033int SharedFunctionInfo::deopt_count() {
4034 return DeoptCountBits::decode(counters());
4035}
4036
4037
4038void SharedFunctionInfo::set_deopt_count(int deopt_count) {
4039 set_counters(DeoptCountBits::update(counters(), deopt_count));
4040}
4041
4042
4043void SharedFunctionInfo::increment_deopt_count() {
4044 int value = counters();
4045 int deopt_count = DeoptCountBits::decode(value);
4046 deopt_count = (deopt_count + 1) & DeoptCountBits::kMax;
4047 set_counters(DeoptCountBits::update(value, deopt_count));
4048}
4049
4050
4051int SharedFunctionInfo::opt_reenable_tries() {
4052 return OptReenableTriesBits::decode(counters());
4053}
4054
4055
4056void SharedFunctionInfo::set_opt_reenable_tries(int tries) {
4057 set_counters(OptReenableTriesBits::update(counters(), tries));
4058}
4059
4060
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004061bool SharedFunctionInfo::has_deoptimization_support() {
4062 Code* code = this->code();
4063 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
4064}
4065
4066
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004067void SharedFunctionInfo::TryReenableOptimization() {
4068 int tries = opt_reenable_tries();
4069 set_opt_reenable_tries((tries + 1) & OptReenableTriesBits::kMax);
4070 // We reenable optimization whenever the number of tries is a large
4071 // enough power of 2.
4072 if (tries >= 16 && (((tries - 1) & tries) == 0)) {
4073 set_optimization_disabled(false);
4074 set_opt_count(0);
4075 set_deopt_count(0);
4076 code()->set_optimizable(true);
4077 }
4078}
4079
4080
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004081bool JSFunction::IsBuiltin() {
4082 return context()->global()->IsJSBuiltinsObject();
4083}
4084
4085
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004086bool JSFunction::NeedsArgumentsAdaption() {
4087 return shared()->formal_parameter_count() !=
4088 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
4089}
4090
4091
4092bool JSFunction::IsOptimized() {
4093 return code()->kind() == Code::OPTIMIZED_FUNCTION;
4094}
4095
4096
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00004097bool JSFunction::IsOptimizable() {
4098 return code()->kind() == Code::FUNCTION && code()->optimizable();
4099}
4100
4101
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004102bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004103 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004104}
4105
4106
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004107Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004108 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004109}
4110
4111
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004112Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004113 return reinterpret_cast<Code*>(
4114 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004115}
4116
4117
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004118void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004119 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004120 Address entry = value->entry();
4121 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004122 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
4123 this,
4124 HeapObject::RawField(this, kCodeEntryOffset),
4125 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004126}
4127
4128
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004129void JSFunction::ReplaceCode(Code* code) {
4130 bool was_optimized = IsOptimized();
4131 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
4132
4133 set_code(code);
4134
4135 // Add/remove the function from the list of optimized functions for this
4136 // context based on the state change.
4137 if (!was_optimized && is_optimized) {
4138 context()->global_context()->AddOptimizedFunction(this);
4139 }
4140 if (was_optimized && !is_optimized) {
4141 context()->global_context()->RemoveOptimizedFunction(this);
4142 }
4143}
4144
4145
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004146Context* JSFunction::context() {
4147 return Context::cast(READ_FIELD(this, kContextOffset));
4148}
4149
4150
4151Object* JSFunction::unchecked_context() {
4152 return READ_FIELD(this, kContextOffset);
4153}
4154
4155
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004156SharedFunctionInfo* JSFunction::unchecked_shared() {
4157 return reinterpret_cast<SharedFunctionInfo*>(
4158 READ_FIELD(this, kSharedFunctionInfoOffset));
4159}
4160
4161
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004162void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004163 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004164 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004165 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004166}
4167
4168ACCESSORS(JSFunction, prototype_or_initial_map, Object,
4169 kPrototypeOrInitialMapOffset)
4170
4171
4172Map* JSFunction::initial_map() {
4173 return Map::cast(prototype_or_initial_map());
4174}
4175
4176
4177void JSFunction::set_initial_map(Map* value) {
4178 set_prototype_or_initial_map(value);
4179}
4180
4181
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004182MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
4183 Map* initial_map) {
4184 Context* global_context = context()->global_context();
4185 Object* array_function =
4186 global_context->get(Context::ARRAY_FUNCTION_INDEX);
4187 if (array_function->IsJSFunction() &&
4188 this == JSFunction::cast(array_function)) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004189 // Replace all of the cached initial array maps in the global context with
4190 // the appropriate transitioned elements kind maps.
4191 Heap* heap = GetHeap();
4192 MaybeObject* maybe_maps =
4193 heap->AllocateFixedArrayWithHoles(kElementsKindCount);
4194 FixedArray* maps;
4195 if (!maybe_maps->To(&maps)) return maybe_maps;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004196
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004197 Map* current_map = initial_map;
4198 ElementsKind kind = current_map->elements_kind();
4199 ASSERT(kind == GetInitialFastElementsKind());
4200 maps->set(kind, current_map);
4201 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
4202 i < kFastElementsKindCount; ++i) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004203 Map* new_map;
4204 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i);
4205 MaybeObject* maybe_new_map =
4206 current_map->CreateNextElementsTransition(next_kind);
4207 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
4208 maps->set(next_kind, new_map);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004209 current_map = new_map;
4210 }
4211 global_context->set_js_array_maps(maps);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004212 }
4213 set_initial_map(initial_map);
4214 return this;
4215}
4216
4217
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004218bool JSFunction::has_initial_map() {
4219 return prototype_or_initial_map()->IsMap();
4220}
4221
4222
4223bool JSFunction::has_instance_prototype() {
4224 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4225}
4226
4227
4228bool JSFunction::has_prototype() {
4229 return map()->has_non_instance_prototype() || has_instance_prototype();
4230}
4231
4232
4233Object* JSFunction::instance_prototype() {
4234 ASSERT(has_instance_prototype());
4235 if (has_initial_map()) return initial_map()->prototype();
4236 // When there is no initial map and the prototype is a JSObject, the
4237 // initial map field is used for the prototype field.
4238 return prototype_or_initial_map();
4239}
4240
4241
4242Object* JSFunction::prototype() {
4243 ASSERT(has_prototype());
4244 // If the function's prototype property has been set to a non-JSObject
4245 // value, that value is stored in the constructor field of the map.
4246 if (map()->has_non_instance_prototype()) return map()->constructor();
4247 return instance_prototype();
4248}
4249
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004250
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00004251bool JSFunction::should_have_prototype() {
4252 return map()->function_with_prototype();
4253}
4254
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004255
4256bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004257 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004258}
4259
4260
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004261FixedArray* JSFunction::literals() {
4262 ASSERT(!shared()->bound());
4263 return literals_or_bindings();
4264}
4265
4266
4267void JSFunction::set_literals(FixedArray* literals) {
4268 ASSERT(!shared()->bound());
4269 set_literals_or_bindings(literals);
4270}
4271
4272
4273FixedArray* JSFunction::function_bindings() {
4274 ASSERT(shared()->bound());
4275 return literals_or_bindings();
4276}
4277
4278
4279void JSFunction::set_function_bindings(FixedArray* bindings) {
4280 ASSERT(shared()->bound());
4281 // Bound function literal may be initialized to the empty fixed array
4282 // before the bindings are set.
4283 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4284 bindings->map() == GetHeap()->fixed_cow_array_map());
4285 set_literals_or_bindings(bindings);
4286}
4287
4288
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004289int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004290 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004291 return literals()->length();
4292}
4293
4294
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004295Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004296 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004297 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004298}
4299
4300
4301void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4302 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004303 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004304 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004305 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004306}
4307
4308
4309Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004310 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004311 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4312}
4313
4314
4315void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4316 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004317 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004318 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004319 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004320}
4321
4322
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004323ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004324ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004325ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4326ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4327
4328
4329void JSProxy::InitializeBody(int object_size, Object* value) {
4330 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4331 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4332 WRITE_FIELD(this, offset, value);
4333 }
4334}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004335
4336
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004337ACCESSORS(JSSet, table, Object, kTableOffset)
4338ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004339ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4340ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004341
4342
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004343Address Foreign::foreign_address() {
4344 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004345}
4346
4347
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004348void Foreign::set_foreign_address(Address value) {
4349 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004350}
4351
4352
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004353ACCESSORS(JSModule, context, Object, kContextOffset)
4354
4355
4356JSModule* JSModule::cast(Object* obj) {
4357 ASSERT(obj->IsJSModule());
4358 ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
4359 return reinterpret_cast<JSModule*>(obj);
4360}
4361
4362
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004363ACCESSORS(JSValue, value, Object, kValueOffset)
4364
4365
4366JSValue* JSValue::cast(Object* obj) {
4367 ASSERT(obj->IsJSValue());
4368 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4369 return reinterpret_cast<JSValue*>(obj);
4370}
4371
4372
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004373ACCESSORS(JSDate, value, Object, kValueOffset)
4374ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4375ACCESSORS(JSDate, year, Object, kYearOffset)
4376ACCESSORS(JSDate, month, Object, kMonthOffset)
4377ACCESSORS(JSDate, day, Object, kDayOffset)
4378ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4379ACCESSORS(JSDate, hour, Object, kHourOffset)
4380ACCESSORS(JSDate, min, Object, kMinOffset)
4381ACCESSORS(JSDate, sec, Object, kSecOffset)
4382
4383
4384JSDate* JSDate::cast(Object* obj) {
4385 ASSERT(obj->IsJSDate());
4386 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4387 return reinterpret_cast<JSDate*>(obj);
4388}
4389
4390
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004391ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4392ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4393ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4394ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4395ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4396SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4397SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4398
4399
4400JSMessageObject* JSMessageObject::cast(Object* obj) {
4401 ASSERT(obj->IsJSMessageObject());
4402 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4403 return reinterpret_cast<JSMessageObject*>(obj);
4404}
4405
4406
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004407INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004408ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004409ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004410ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004411ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004412ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00004413INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004414
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004415byte* Code::instruction_start() {
4416 return FIELD_ADDR(this, kHeaderSize);
4417}
4418
4419
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004420byte* Code::instruction_end() {
4421 return instruction_start() + instruction_size();
4422}
4423
4424
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004425int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004426 return RoundUp(instruction_size(), kObjectAlignment);
4427}
4428
4429
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004430FixedArray* Code::unchecked_deoptimization_data() {
4431 return reinterpret_cast<FixedArray*>(
4432 READ_FIELD(this, kDeoptimizationDataOffset));
4433}
4434
4435
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004436ByteArray* Code::unchecked_relocation_info() {
4437 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004438}
4439
4440
4441byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004442 return unchecked_relocation_info()->GetDataStartAddress();
4443}
4444
4445
4446int Code::relocation_size() {
4447 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004448}
4449
4450
4451byte* Code::entry() {
4452 return instruction_start();
4453}
4454
4455
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004456bool Code::contains(byte* inner_pointer) {
4457 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004458}
4459
4460
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004461ACCESSORS(JSArray, length, Object, kLengthOffset)
4462
4463
ager@chromium.org236ad962008-09-25 09:45:57 +00004464ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004465
4466
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004467JSRegExp::Type JSRegExp::TypeTag() {
4468 Object* data = this->data();
4469 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4470 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4471 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004472}
4473
4474
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004475JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4476 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4477 return static_cast<JSRegExp::Type>(smi->value());
4478}
4479
4480
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004481int JSRegExp::CaptureCount() {
4482 switch (TypeTag()) {
4483 case ATOM:
4484 return 0;
4485 case IRREGEXP:
4486 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4487 default:
4488 UNREACHABLE();
4489 return -1;
4490 }
4491}
4492
4493
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004494JSRegExp::Flags JSRegExp::GetFlags() {
4495 ASSERT(this->data()->IsFixedArray());
4496 Object* data = this->data();
4497 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4498 return Flags(smi->value());
4499}
4500
4501
4502String* JSRegExp::Pattern() {
4503 ASSERT(this->data()->IsFixedArray());
4504 Object* data = this->data();
4505 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4506 return pattern;
4507}
4508
4509
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004510Object* JSRegExp::DataAt(int index) {
4511 ASSERT(TypeTag() != NOT_COMPILED);
4512 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004513}
4514
4515
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004516Object* JSRegExp::DataAtUnchecked(int index) {
4517 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4518 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4519 return READ_FIELD(fa, offset);
4520}
4521
4522
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004523void JSRegExp::SetDataAt(int index, Object* value) {
4524 ASSERT(TypeTag() != NOT_COMPILED);
4525 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4526 FixedArray::cast(data())->set(index, value);
4527}
4528
4529
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004530void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4531 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4532 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4533 if (value->IsSmi()) {
4534 fa->set_unchecked(index, Smi::cast(value));
4535 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004536 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004537 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4538 }
4539}
4540
4541
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004542ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004543 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004544#if DEBUG
4545 FixedArrayBase* fixed_array =
4546 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4547 Map* map = fixed_array->map();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004548 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
4549 (map == GetHeap()->fixed_array_map() ||
4550 map == GetHeap()->fixed_cow_array_map())) ||
4551 (IsFastDoubleElementsKind(kind) &&
4552 (fixed_array->IsFixedDoubleArray() ||
4553 fixed_array == GetHeap()->empty_fixed_array())) ||
4554 (kind == DICTIONARY_ELEMENTS &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004555 fixed_array->IsFixedArray() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004556 fixed_array->IsDictionary()) ||
4557 (kind > DICTIONARY_ELEMENTS));
4558 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4559 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004560#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004561 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004562}
4563
4564
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004565ElementsAccessor* JSObject::GetElementsAccessor() {
4566 return ElementsAccessor::ForKind(GetElementsKind());
4567}
4568
4569
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004570bool JSObject::HasFastObjectElements() {
4571 return IsFastObjectElementsKind(GetElementsKind());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004572}
4573
4574
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004575bool JSObject::HasFastSmiElements() {
4576 return IsFastSmiElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004577}
4578
4579
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004580bool JSObject::HasFastSmiOrObjectElements() {
4581 return IsFastSmiOrObjectElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004582}
4583
4584
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004585bool JSObject::HasFastDoubleElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004586 return IsFastDoubleElementsKind(GetElementsKind());
4587}
4588
4589
4590bool JSObject::HasFastHoleyElements() {
4591 return IsFastHoleyElementsKind(GetElementsKind());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004592}
4593
4594
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004595bool JSObject::HasDictionaryElements() {
4596 return GetElementsKind() == DICTIONARY_ELEMENTS;
4597}
4598
4599
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004600bool JSObject::HasNonStrictArgumentsElements() {
4601 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4602}
4603
4604
ager@chromium.org3811b432009-10-28 14:53:37 +00004605bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004606 HeapObject* array = elements();
4607 ASSERT(array != NULL);
4608 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004609}
4610
4611
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004612#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4613bool JSObject::HasExternal##name##Elements() { \
4614 HeapObject* array = elements(); \
4615 ASSERT(array != NULL); \
4616 if (!array->IsHeapObject()) \
4617 return false; \
4618 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004619}
4620
4621
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004622EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4623EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4624EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4625EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4626 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4627EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4628EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4629 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4630EXTERNAL_ELEMENTS_CHECK(Float,
4631 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004632EXTERNAL_ELEMENTS_CHECK(Double,
4633 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004634EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004635
4636
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004637bool JSObject::HasNamedInterceptor() {
4638 return map()->has_named_interceptor();
4639}
4640
4641
4642bool JSObject::HasIndexedInterceptor() {
4643 return map()->has_indexed_interceptor();
4644}
4645
4646
lrn@chromium.org303ada72010-10-27 09:33:13 +00004647MaybeObject* JSObject::EnsureWritableFastElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004648 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004649 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004650 Isolate* isolate = GetIsolate();
4651 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004652 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004653 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4654 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004655 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4656 return maybe_writable_elems;
4657 }
4658 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004659 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004660 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004661 return writable_elems;
4662}
4663
4664
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004665StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004666 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004667 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004668}
4669
4670
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004671SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004672 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004673 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004674}
4675
4676
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004677bool String::IsHashFieldComputed(uint32_t field) {
4678 return (field & kHashNotComputedMask) == 0;
4679}
4680
4681
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004682bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004683 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004684}
4685
4686
4687uint32_t String::Hash() {
4688 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004689 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004690 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004691 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004692 return ComputeAndSetHash();
4693}
4694
4695
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004696StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004697 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004698 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004699 array_index_(0),
4700 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4701 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004702 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004703 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004704}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004705
4706
4707bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004708 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004709}
4710
4711
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004712void StringHasher::AddCharacter(uint32_t c) {
4713 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4714 AddSurrogatePair(c); // Not inlined.
4715 return;
4716 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004717 // Use the Jenkins one-at-a-time hash function to update the hash
4718 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004719 raw_running_hash_ += c;
4720 raw_running_hash_ += (raw_running_hash_ << 10);
4721 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004722 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004723 if (is_array_index_) {
4724 if (c < '0' || c > '9') {
4725 is_array_index_ = false;
4726 } else {
4727 int d = c - '0';
4728 if (is_first_char_) {
4729 is_first_char_ = false;
4730 if (c == '0' && length_ > 1) {
4731 is_array_index_ = false;
4732 return;
4733 }
4734 }
4735 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4736 is_array_index_ = false;
4737 } else {
4738 array_index_ = array_index_ * 10 + d;
4739 }
4740 }
4741 }
4742}
4743
4744
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004745void StringHasher::AddCharacterNoIndex(uint32_t c) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00004746 ASSERT(!is_array_index());
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004747 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4748 AddSurrogatePairNoIndex(c); // Not inlined.
4749 return;
4750 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004751 raw_running_hash_ += c;
4752 raw_running_hash_ += (raw_running_hash_ << 10);
4753 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4754}
4755
4756
4757uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004758 // Get the calculated raw hash value and do some more bit ops to distribute
4759 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004760 uint32_t result = raw_running_hash_;
4761 result += (result << 3);
4762 result ^= (result >> 11);
4763 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004764 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004765 result = 27;
4766 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004767 return result;
4768}
4769
4770
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004771template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004772uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4773 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004774 if (!hasher.has_trivial_hash()) {
4775 int i;
4776 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4777 hasher.AddCharacter(chars[i]);
4778 }
4779 for (; i < length; i++) {
4780 hasher.AddCharacterNoIndex(chars[i]);
4781 }
4782 }
4783 return hasher.GetHashField();
4784}
4785
4786
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004787bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004788 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004789 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4790 return false;
4791 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004792 return SlowAsArrayIndex(index);
4793}
4794
4795
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004796Object* JSReceiver::GetPrototype() {
4797 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004798}
4799
4800
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00004801Object* JSReceiver::GetConstructor() {
4802 return map()->constructor();
4803}
4804
4805
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004806bool JSReceiver::HasProperty(String* name) {
4807 if (IsJSProxy()) {
4808 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4809 }
4810 return GetPropertyAttribute(name) != ABSENT;
4811}
4812
4813
4814bool JSReceiver::HasLocalProperty(String* name) {
4815 if (IsJSProxy()) {
4816 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4817 }
4818 return GetLocalPropertyAttribute(name) != ABSENT;
4819}
4820
4821
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004822PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004823 return GetPropertyAttributeWithReceiver(this, key);
4824}
4825
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004826// TODO(504): this may be useful in other places too where JSGlobalProxy
4827// is used.
4828Object* JSObject::BypassGlobalProxy() {
4829 if (IsJSGlobalProxy()) {
4830 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004831 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004832 ASSERT(proto->IsJSGlobalObject());
4833 return proto;
4834 }
4835 return this;
4836}
4837
4838
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004839MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4840 return IsJSProxy()
4841 ? JSProxy::cast(this)->GetIdentityHash(flag)
4842 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004843}
4844
4845
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004846bool JSReceiver::HasElement(uint32_t index) {
4847 if (IsJSProxy()) {
4848 return JSProxy::cast(this)->HasElementWithHandler(index);
4849 }
4850 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004851}
4852
4853
4854bool AccessorInfo::all_can_read() {
4855 return BooleanBit::get(flag(), kAllCanReadBit);
4856}
4857
4858
4859void AccessorInfo::set_all_can_read(bool value) {
4860 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4861}
4862
4863
4864bool AccessorInfo::all_can_write() {
4865 return BooleanBit::get(flag(), kAllCanWriteBit);
4866}
4867
4868
4869void AccessorInfo::set_all_can_write(bool value) {
4870 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4871}
4872
4873
ager@chromium.org870a0b62008-11-04 11:43:05 +00004874bool AccessorInfo::prohibits_overwriting() {
4875 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4876}
4877
4878
4879void AccessorInfo::set_prohibits_overwriting(bool value) {
4880 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4881}
4882
4883
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004884PropertyAttributes AccessorInfo::property_attributes() {
4885 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4886}
4887
4888
4889void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004890 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004891}
4892
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004893
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004894bool AccessorInfo::IsCompatibleReceiver(Object* receiver) {
4895 Object* function_template = expected_receiver_type();
4896 if (!function_template->IsFunctionTemplateInfo()) return true;
4897 return receiver->IsInstanceOf(FunctionTemplateInfo::cast(function_template));
4898}
4899
4900
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004901template<typename Shape, typename Key>
4902void Dictionary<Shape, Key>::SetEntry(int entry,
4903 Object* key,
4904 Object* value) {
4905 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4906}
4907
4908
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004909template<typename Shape, typename Key>
4910void Dictionary<Shape, Key>::SetEntry(int entry,
4911 Object* key,
4912 Object* value,
4913 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004914 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004915 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004916 AssertNoAllocation no_gc;
4917 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004918 FixedArray::set(index, key, mode);
4919 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004920 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004921}
4922
4923
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004924bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4925 ASSERT(other->IsNumber());
4926 return key == static_cast<uint32_t>(other->Number());
4927}
4928
4929
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004930uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
4931 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004932}
4933
4934
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004935uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
4936 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004937 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004938 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004939}
4940
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004941uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
4942 return ComputeIntegerHash(key, seed);
4943}
4944
4945uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
4946 uint32_t seed,
4947 Object* other) {
4948 ASSERT(other->IsNumber());
4949 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
4950}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004951
4952MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4953 return Isolate::Current()->heap()->NumberFromUint32(key);
4954}
4955
4956
4957bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4958 // We know that all entries in a hash table had their hash keys created.
4959 // Use that knowledge to have fast failure.
4960 if (key->Hash() != String::cast(other)->Hash()) return false;
4961 return key->Equals(String::cast(other));
4962}
4963
4964
4965uint32_t StringDictionaryShape::Hash(String* key) {
4966 return key->Hash();
4967}
4968
4969
4970uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4971 return String::cast(other)->Hash();
4972}
4973
4974
4975MaybeObject* StringDictionaryShape::AsObject(String* key) {
4976 return key;
4977}
4978
4979
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004980template <int entrysize>
4981bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4982 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004983}
4984
4985
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004986template <int entrysize>
4987uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004988 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4989 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004990}
4991
4992
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004993template <int entrysize>
4994uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4995 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004996 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4997 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004998}
4999
5000
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005001template <int entrysize>
5002MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005003 return key;
5004}
5005
5006
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005007void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005008 // No write barrier is needed since empty_fixed_array is not in new space.
5009 // Please note this function is used during marking:
5010 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00005011 // - IncrementalMarking::Step
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005012 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
5013 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005014}
5015
5016
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005017void JSArray::EnsureSize(int required_size) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005018 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005019 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005020 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
5021 if (elts->length() < required_size) {
5022 // Doubling in size would be overkill, but leave some slack to avoid
5023 // constantly growing.
5024 Expand(required_size + (required_size >> 3));
5025 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005026 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005027 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
5028 // Expand will allocate a new backing store in new space even if the size
5029 // we asked for isn't larger than what we had before.
5030 Expand(required_size);
5031 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005032}
5033
5034
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005035void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005036 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005037 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
5038}
5039
5040
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005041bool JSArray::AllowsSetElementsLength() {
5042 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
5043 ASSERT(result == !HasExternalArrayElements());
5044 return result;
5045}
5046
5047
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005048MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
5049 MaybeObject* maybe_result = EnsureCanContainElements(
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005050 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005051 if (maybe_result->IsFailure()) return maybe_result;
5052 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005053 IsFastDoubleElementsKind(GetElementsKind())) ||
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005054 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005055 (IsFastObjectElementsKind(GetElementsKind()) ||
5056 (IsFastSmiElementsKind(GetElementsKind()) &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005057 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00005058 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005059 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005060 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005061}
5062
5063
lrn@chromium.org303ada72010-10-27 09:33:13 +00005064MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005065 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005066 return GetHeap()->CopyFixedArray(this);
5067}
5068
5069
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005070MaybeObject* FixedDoubleArray::Copy() {
5071 if (length() == 0) return this;
5072 return GetHeap()->CopyFixedDoubleArray(this);
5073}
5074
5075
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005076void TypeFeedbackCells::SetAstId(int index, Smi* id) {
5077 set(1 + index * 2, id);
5078}
5079
5080
5081Smi* TypeFeedbackCells::AstId(int index) {
5082 return Smi::cast(get(1 + index * 2));
5083}
5084
5085
5086void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
5087 set(index * 2, cell);
5088}
5089
5090
5091JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
5092 return JSGlobalPropertyCell::cast(get(index * 2));
5093}
5094
5095
5096Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
5097 return isolate->factory()->the_hole_value();
5098}
5099
5100
5101Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
5102 return isolate->factory()->undefined_value();
5103}
5104
5105
5106Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
5107 return heap->raw_unchecked_the_hole_value();
5108}
5109
5110
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005111SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00005112SMI_ACCESSORS(TypeFeedbackInfo, ic_with_type_info_count,
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005113 kIcWithTypeinfoCountOffset)
5114ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
5115 kTypeFeedbackCellsOffset)
5116
5117
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00005118SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
5119
5120
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005121Relocatable::Relocatable(Isolate* isolate) {
5122 ASSERT(isolate == Isolate::Current());
5123 isolate_ = isolate;
5124 prev_ = isolate->relocatable_top();
5125 isolate->set_relocatable_top(this);
5126}
5127
5128
5129Relocatable::~Relocatable() {
5130 ASSERT(isolate_ == Isolate::Current());
5131 ASSERT_EQ(isolate_->relocatable_top(), this);
5132 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005133}
5134
5135
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005136int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
5137 return map->instance_size();
5138}
5139
5140
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005141void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005142 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005143 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005144}
5145
5146
5147template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00005148void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005149 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005150 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00005151}
5152
5153
5154void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
5155 typedef v8::String::ExternalAsciiStringResource Resource;
5156 v->VisitExternalAsciiString(
5157 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5158}
5159
5160
5161template<typename StaticVisitor>
5162void ExternalAsciiString::ExternalAsciiStringIterateBody() {
5163 typedef v8::String::ExternalAsciiStringResource Resource;
5164 StaticVisitor::VisitExternalAsciiString(
5165 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5166}
5167
5168
5169void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
5170 typedef v8::String::ExternalStringResource Resource;
5171 v->VisitExternalTwoByteString(
5172 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5173}
5174
5175
5176template<typename StaticVisitor>
5177void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
5178 typedef v8::String::ExternalStringResource Resource;
5179 StaticVisitor::VisitExternalTwoByteString(
5180 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5181}
5182
5183#define SLOT_ADDR(obj, offset) \
5184 reinterpret_cast<Object**>((obj)->address() + offset)
5185
5186template<int start_offset, int end_offset, int size>
5187void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
5188 HeapObject* obj,
5189 ObjectVisitor* v) {
5190 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
5191}
5192
5193
5194template<int start_offset>
5195void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
5196 int object_size,
5197 ObjectVisitor* v) {
5198 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
5199}
5200
5201#undef SLOT_ADDR
5202
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005203#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005204#undef CAST_ACCESSOR
5205#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005206#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005207#undef ACCESSORS_TO_SMI
5208#undef SMI_ACCESSORS
5209#undef BOOL_GETTER
5210#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005211#undef FIELD_ADDR
5212#undef READ_FIELD
5213#undef WRITE_FIELD
5214#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005215#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005216#undef READ_DOUBLE_FIELD
5217#undef WRITE_DOUBLE_FIELD
5218#undef READ_INT_FIELD
5219#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005220#undef READ_INTPTR_FIELD
5221#undef WRITE_INTPTR_FIELD
5222#undef READ_UINT32_FIELD
5223#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005224#undef READ_SHORT_FIELD
5225#undef WRITE_SHORT_FIELD
5226#undef READ_BYTE_FIELD
5227#undef WRITE_BYTE_FIELD
5228
5229
5230} } // namespace v8::internal
5231
5232#endif // V8_OBJECTS_INL_H_