blob: 7308fb2bc3ca4792c319b5c4648d3c55857e424f [file] [log] [blame]
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001// Copyright 2011 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"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000048
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
97#define SMI_ACCESSORS(holder, name, offset) \
98 int holder::name() { \
99 Object* value = READ_FIELD(this, offset); \
100 return Smi::cast(value)->value(); \
101 } \
102 void holder::set_##name(int value) { \
103 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
104 }
105
106
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000107#define BOOL_GETTER(holder, field, name, offset) \
108 bool holder::name() { \
109 return BooleanBit::get(field(), offset); \
110 } \
111
112
113#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000114 bool holder::name() { \
115 return BooleanBit::get(field(), offset); \
116 } \
117 void holder::set_##name(bool value) { \
118 set_##field(BooleanBit::set(field(), offset, value)); \
119 }
120
121
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000122bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
123 ElementsKind to_kind) {
124 if (to_kind == FAST_ELEMENTS) {
125 return from_kind == FAST_SMI_ONLY_ELEMENTS ||
126 from_kind == FAST_DOUBLE_ELEMENTS;
127 } else {
128 return to_kind == FAST_DOUBLE_ELEMENTS &&
129 from_kind == FAST_SMI_ONLY_ELEMENTS;
130 }
131}
132
133
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000134bool Object::IsFixedArrayBase() {
135 return IsFixedArray() || IsFixedDoubleArray();
136}
137
138
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000139bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
140 // There is a constraint on the object; check.
141 if (!this->IsJSObject()) return false;
142 // Fetch the constructor function of the object.
143 Object* cons_obj = JSObject::cast(this)->map()->constructor();
144 if (!cons_obj->IsJSFunction()) return false;
145 JSFunction* fun = JSFunction::cast(cons_obj);
146 // Iterate through the chain of inheriting function templates to
147 // see if the required one occurs.
148 for (Object* type = fun->shared()->function_data();
149 type->IsFunctionTemplateInfo();
150 type = FunctionTemplateInfo::cast(type)->parent_template()) {
151 if (type == expected) return true;
152 }
153 // Didn't find the required type in the inheritance chain.
154 return false;
155}
156
157
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000158bool Object::IsSmi() {
159 return HAS_SMI_TAG(this);
160}
161
162
163bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000164 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000165}
166
167
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000168bool Object::NonFailureIsHeapObject() {
169 ASSERT(!this->IsFailure());
170 return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0;
171}
172
173
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000174TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000175
176
177bool Object::IsString() {
178 return Object::IsHeapObject()
179 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
180}
181
182
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000183bool Object::IsSpecObject() {
184 return Object::IsHeapObject()
185 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
186}
187
188
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000189bool Object::IsSpecFunction() {
190 if (!Object::IsHeapObject()) return false;
191 InstanceType type = HeapObject::cast(this)->map()->instance_type();
192 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
193}
194
195
ager@chromium.org870a0b62008-11-04 11:43:05 +0000196bool Object::IsSymbol() {
197 if (!this->IsHeapObject()) return false;
198 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000199 // Because the symbol tag is non-zero and no non-string types have the
200 // symbol bit set we can test for symbols with a very simple test
201 // operation.
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000202 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000203 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
204 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000205}
206
207
208bool Object::IsConsString() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000209 if (!IsString()) return false;
210 return StringShape(String::cast(this)).IsCons();
211}
212
213
214bool Object::IsSlicedString() {
215 if (!IsString()) return false;
216 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000217}
218
219
ager@chromium.org870a0b62008-11-04 11:43:05 +0000220bool Object::IsSeqString() {
221 if (!IsString()) return false;
222 return StringShape(String::cast(this)).IsSequential();
223}
224
225
226bool Object::IsSeqAsciiString() {
227 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000228 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000229 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000230}
231
232
233bool Object::IsSeqTwoByteString() {
234 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000235 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000236 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000237}
238
239
240bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000241 if (!IsString()) return false;
242 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000243}
244
245
246bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000247 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000248 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000249 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000250}
251
252
253bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000254 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000255 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000256 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000257}
258
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000259bool Object::HasValidElements() {
260 // Dictionary is covered under FixedArray.
261 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
262}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000263
ager@chromium.org870a0b62008-11-04 11:43:05 +0000264StringShape::StringShape(String* str)
265 : type_(str->map()->instance_type()) {
266 set_valid();
267 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000268}
269
270
ager@chromium.org870a0b62008-11-04 11:43:05 +0000271StringShape::StringShape(Map* map)
272 : type_(map->instance_type()) {
273 set_valid();
274 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000275}
276
277
ager@chromium.org870a0b62008-11-04 11:43:05 +0000278StringShape::StringShape(InstanceType t)
279 : type_(static_cast<uint32_t>(t)) {
280 set_valid();
281 ASSERT((type_ & kIsNotStringMask) == kStringTag);
282}
283
284
285bool StringShape::IsSymbol() {
286 ASSERT(valid());
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000287 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000288 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000289}
290
291
ager@chromium.org5ec48922009-05-05 07:25:34 +0000292bool String::IsAsciiRepresentation() {
293 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000294 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000295}
296
297
ager@chromium.org5ec48922009-05-05 07:25:34 +0000298bool String::IsTwoByteRepresentation() {
299 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000300 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000301}
302
303
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000304bool String::IsAsciiRepresentationUnderneath() {
305 uint32_t type = map()->instance_type();
306 STATIC_ASSERT(kIsIndirectStringTag != 0);
307 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
308 ASSERT(IsFlat());
309 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
310 case kAsciiStringTag:
311 return true;
312 case kTwoByteStringTag:
313 return false;
314 default: // Cons or sliced string. Need to go deeper.
315 return GetUnderlying()->IsAsciiRepresentation();
316 }
317}
318
319
320bool String::IsTwoByteRepresentationUnderneath() {
321 uint32_t type = map()->instance_type();
322 STATIC_ASSERT(kIsIndirectStringTag != 0);
323 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
324 ASSERT(IsFlat());
325 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
326 case kAsciiStringTag:
327 return false;
328 case kTwoByteStringTag:
329 return true;
330 default: // Cons or sliced string. Need to go deeper.
331 return GetUnderlying()->IsTwoByteRepresentation();
332 }
333}
334
335
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000336bool String::HasOnlyAsciiChars() {
337 uint32_t type = map()->instance_type();
338 return (type & kStringEncodingMask) == kAsciiStringTag ||
339 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000340}
341
342
ager@chromium.org870a0b62008-11-04 11:43:05 +0000343bool StringShape::IsCons() {
344 return (type_ & kStringRepresentationMask) == kConsStringTag;
345}
346
347
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000348bool StringShape::IsSliced() {
349 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
350}
351
352
353bool StringShape::IsIndirect() {
354 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
355}
356
357
ager@chromium.org870a0b62008-11-04 11:43:05 +0000358bool StringShape::IsExternal() {
359 return (type_ & kStringRepresentationMask) == kExternalStringTag;
360}
361
362
363bool StringShape::IsSequential() {
364 return (type_ & kStringRepresentationMask) == kSeqStringTag;
365}
366
367
368StringRepresentationTag StringShape::representation_tag() {
369 uint32_t tag = (type_ & kStringRepresentationMask);
370 return static_cast<StringRepresentationTag>(tag);
371}
372
373
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000374uint32_t StringShape::encoding_tag() {
375 return type_ & kStringEncodingMask;
376}
377
378
ager@chromium.org870a0b62008-11-04 11:43:05 +0000379uint32_t StringShape::full_representation_tag() {
380 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
381}
382
383
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000384STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
385 Internals::kFullStringRepresentationMask);
386
387
ager@chromium.org870a0b62008-11-04 11:43:05 +0000388bool StringShape::IsSequentialAscii() {
389 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
390}
391
392
393bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000394 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000395}
396
397
398bool StringShape::IsExternalAscii() {
399 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
400}
401
402
403bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000404 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000405}
406
407
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000408STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
409 Internals::kExternalTwoByteRepresentationTag);
410
411
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000412uc32 FlatStringReader::Get(int index) {
413 ASSERT(0 <= index && index <= length_);
414 if (is_ascii_) {
415 return static_cast<const byte*>(start_)[index];
416 } else {
417 return static_cast<const uc16*>(start_)[index];
418 }
419}
420
421
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000422bool Object::IsNumber() {
423 return IsSmi() || IsHeapNumber();
424}
425
426
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000427TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
428TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000429
430
431bool Object::IsFiller() {
432 if (!Object::IsHeapObject()) return false;
433 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
434 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
435}
436
437
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000438TYPE_CHECKER(ExternalPixelArray, EXTERNAL_PIXEL_ARRAY_TYPE)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000439
440
ager@chromium.org3811b432009-10-28 14:53:37 +0000441bool Object::IsExternalArray() {
442 if (!Object::IsHeapObject())
443 return false;
444 InstanceType instance_type =
445 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000446 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
447 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000448}
449
450
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000451TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE)
452TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
453TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE)
454TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
455TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE)
456TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
457TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE)
458TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000459
460
lrn@chromium.org303ada72010-10-27 09:33:13 +0000461bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000462 return HAS_FAILURE_TAG(this);
463}
464
465
lrn@chromium.org303ada72010-10-27 09:33:13 +0000466bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000467 return HAS_FAILURE_TAG(this)
468 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
469}
470
471
lrn@chromium.org303ada72010-10-27 09:33:13 +0000472bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000473 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000474 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000475}
476
477
lrn@chromium.org303ada72010-10-27 09:33:13 +0000478bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000479 return this == Failure::Exception();
480}
481
482
lrn@chromium.org303ada72010-10-27 09:33:13 +0000483bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000484 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000485}
486
487
488Failure* Failure::cast(MaybeObject* obj) {
489 ASSERT(HAS_FAILURE_TAG(obj));
490 return reinterpret_cast<Failure*>(obj);
491}
492
493
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000494bool Object::IsJSReceiver() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000495 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000496 return IsHeapObject() &&
497 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
498}
499
500
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000501bool Object::IsJSObject() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000502 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
503 return IsHeapObject() &&
504 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000505}
506
507
508bool Object::IsJSProxy() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000509 if (!Object::IsHeapObject()) return false;
510 InstanceType type = HeapObject::cast(this)->map()->instance_type();
511 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000512}
513
514
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000515TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
516TYPE_CHECKER(JSSet, JS_SET_TYPE)
517TYPE_CHECKER(JSMap, JS_MAP_TYPE)
518TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
519TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
520TYPE_CHECKER(Map, MAP_TYPE)
521TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
522TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000523
524
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000525bool Object::IsDescriptorArray() {
526 return IsFixedArray();
527}
528
529
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000530bool Object::IsDeoptimizationInputData() {
531 // Must be a fixed array.
532 if (!IsFixedArray()) return false;
533
534 // There's no sure way to detect the difference between a fixed array and
535 // a deoptimization data array. Since this is used for asserts we can
536 // check that the length is zero or else the fixed size plus a multiple of
537 // the entry size.
538 int length = FixedArray::cast(this)->length();
539 if (length == 0) return true;
540
541 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
542 return length >= 0 &&
543 length % DeoptimizationInputData::kDeoptEntrySize == 0;
544}
545
546
547bool Object::IsDeoptimizationOutputData() {
548 if (!IsFixedArray()) return false;
549 // There's actually no way to see the difference between a fixed array and
550 // a deoptimization data array. Since this is used for asserts we can check
551 // that the length is plausible though.
552 if (FixedArray::cast(this)->length() % 2 != 0) return false;
553 return true;
554}
555
556
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000557bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000558 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000559 Map* map = HeapObject::cast(this)->map();
560 Heap* heap = map->GetHeap();
561 return (map == heap->function_context_map() ||
562 map == heap->catch_context_map() ||
563 map == heap->with_context_map() ||
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000564 map == heap->global_context_map() ||
565 map == heap->block_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000566 }
567 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000568}
569
570
571bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000572 return Object::IsHeapObject() &&
573 HeapObject::cast(this)->map() ==
574 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000575}
576
577
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000578bool Object::IsScopeInfo() {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000579 return Object::IsHeapObject() &&
580 HeapObject::cast(this)->map() ==
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000581 HeapObject::cast(this)->GetHeap()->scope_info_map();
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000582}
583
584
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000585TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000586
587
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000588template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000589 return obj->IsJSFunction();
590}
591
592
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000593TYPE_CHECKER(Code, CODE_TYPE)
594TYPE_CHECKER(Oddball, ODDBALL_TYPE)
595TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
596TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
597TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
598TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000599
600
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000601bool Object::IsStringWrapper() {
602 return IsJSValue() && JSValue::cast(this)->value()->IsString();
603}
604
605
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000606TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000607
608
609bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000610 return IsOddball() &&
611 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000612}
613
614
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000615TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
616TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000617
618
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000619template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000620 return obj->IsJSArray();
621}
622
623
624bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000625 return Object::IsHeapObject() &&
626 HeapObject::cast(this)->map() ==
627 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000628}
629
630
631bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000632 return IsHashTable() &&
633 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000634}
635
636
637bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000638 return IsHashTable() && this ==
639 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000640}
641
642
ager@chromium.orgac091b72010-05-05 07:34:42 +0000643bool Object::IsJSFunctionResultCache() {
644 if (!IsFixedArray()) return false;
645 FixedArray* self = FixedArray::cast(this);
646 int length = self->length();
647 if (length < JSFunctionResultCache::kEntriesIndex) return false;
648 if ((length - JSFunctionResultCache::kEntriesIndex)
649 % JSFunctionResultCache::kEntrySize != 0) {
650 return false;
651 }
652#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000653 if (FLAG_verify_heap) {
654 reinterpret_cast<JSFunctionResultCache*>(this)->
655 JSFunctionResultCacheVerify();
656 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000657#endif
658 return true;
659}
660
661
ricow@chromium.org65fae842010-08-25 15:26:24 +0000662bool Object::IsNormalizedMapCache() {
663 if (!IsFixedArray()) return false;
664 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
665 return false;
666 }
667#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000668 if (FLAG_verify_heap) {
669 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
670 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000671#endif
672 return true;
673}
674
675
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000676bool Object::IsCompilationCacheTable() {
677 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000678}
679
680
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000681bool Object::IsCodeCacheHashTable() {
682 return IsHashTable();
683}
684
685
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000686bool Object::IsPolymorphicCodeCacheHashTable() {
687 return IsHashTable();
688}
689
690
ager@chromium.org236ad962008-09-25 09:45:57 +0000691bool Object::IsMapCache() {
692 return IsHashTable();
693}
694
695
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000696bool Object::IsPrimitive() {
697 return IsOddball() || IsNumber() || IsString();
698}
699
700
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000701bool Object::IsJSGlobalProxy() {
702 bool result = IsHeapObject() &&
703 (HeapObject::cast(this)->map()->instance_type() ==
704 JS_GLOBAL_PROXY_TYPE);
705 ASSERT(!result || IsAccessCheckNeeded());
706 return result;
707}
708
709
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000710bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000711 if (!IsHeapObject()) return false;
712
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000713 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000714 return type == JS_GLOBAL_OBJECT_TYPE ||
715 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000716}
717
718
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000719TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
720TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000721
722
723bool Object::IsUndetectableObject() {
724 return IsHeapObject()
725 && HeapObject::cast(this)->map()->is_undetectable();
726}
727
728
729bool Object::IsAccessCheckNeeded() {
730 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000731 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000732}
733
734
735bool Object::IsStruct() {
736 if (!IsHeapObject()) return false;
737 switch (HeapObject::cast(this)->map()->instance_type()) {
738#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
739 STRUCT_LIST(MAKE_STRUCT_CASE)
740#undef MAKE_STRUCT_CASE
741 default: return false;
742 }
743}
744
745
746#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
747 bool Object::Is##Name() { \
748 return Object::IsHeapObject() \
749 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
750 }
751 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
752#undef MAKE_STRUCT_PREDICATE
753
754
755bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000756 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000757}
758
759
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000760bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000761 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
762}
763
764
765bool Object::IsTheHole() {
766 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000767}
768
769
770bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000771 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000772}
773
774
775bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000776 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000777}
778
779
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000780bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000781 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000782}
783
784
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000785double Object::Number() {
786 ASSERT(IsNumber());
787 return IsSmi()
788 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
789 : reinterpret_cast<HeapNumber*>(this)->value();
790}
791
792
lrn@chromium.org303ada72010-10-27 09:33:13 +0000793MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000794 if (IsSmi()) return this;
795 if (IsHeapNumber()) {
796 double value = HeapNumber::cast(this)->value();
797 int int_value = FastD2I(value);
798 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
799 return Smi::FromInt(int_value);
800 }
801 }
802 return Failure::Exception();
803}
804
805
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000806bool Object::HasSpecificClassOf(String* name) {
807 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
808}
809
810
lrn@chromium.org303ada72010-10-27 09:33:13 +0000811MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000812 // GetElement can trigger a getter which can cause allocation.
813 // This was not always the case. This ASSERT is here to catch
814 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000815 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000816 return GetElementWithReceiver(this, index);
817}
818
819
lrn@chromium.org303ada72010-10-27 09:33:13 +0000820Object* Object::GetElementNoExceptionThrown(uint32_t index) {
821 MaybeObject* maybe = GetElementWithReceiver(this, index);
822 ASSERT(!maybe->IsFailure());
823 Object* result = NULL; // Initialization to please compiler.
824 maybe->ToObject(&result);
825 return result;
826}
827
828
829MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000830 PropertyAttributes attributes;
831 return GetPropertyWithReceiver(this, key, &attributes);
832}
833
834
lrn@chromium.org303ada72010-10-27 09:33:13 +0000835MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000836 return GetPropertyWithReceiver(this, key, attributes);
837}
838
839
840#define FIELD_ADDR(p, offset) \
841 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
842
843#define READ_FIELD(p, offset) \
844 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
845
846#define WRITE_FIELD(p, offset, value) \
847 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
848
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000849#define WRITE_BARRIER(heap, object, offset, value) \
850 heap->incremental_marking()->RecordWrite( \
851 object, HeapObject::RawField(object, offset), value); \
852 if (heap->InNewSpace(value)) { \
853 heap->RecordWrite(object->address(), offset); \
854 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000855
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000856#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
857 if (mode == UPDATE_WRITE_BARRIER) { \
858 heap->incremental_marking()->RecordWrite( \
859 object, HeapObject::RawField(object, offset), value); \
860 if (heap->InNewSpace(value)) { \
861 heap->RecordWrite(object->address(), offset); \
862 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000863 }
864
lrn@chromium.org7516f052011-03-30 08:52:27 +0000865#ifndef V8_TARGET_ARCH_MIPS
866 #define READ_DOUBLE_FIELD(p, offset) \
867 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
868#else // V8_TARGET_ARCH_MIPS
869 // Prevent gcc from using load-double (mips ldc1) on (possibly)
870 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000871 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000872 union conversion {
873 double d;
874 uint32_t u[2];
875 } c;
876 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
877 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
878 return c.d;
879 }
880 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
881#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000882
lrn@chromium.org7516f052011-03-30 08:52:27 +0000883#ifndef V8_TARGET_ARCH_MIPS
884 #define WRITE_DOUBLE_FIELD(p, offset, value) \
885 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
886#else // V8_TARGET_ARCH_MIPS
887 // Prevent gcc from using store-double (mips sdc1) on (possibly)
888 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000889 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000890 double value) {
891 union conversion {
892 double d;
893 uint32_t u[2];
894 } c;
895 c.d = value;
896 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
897 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
898 }
899 #define WRITE_DOUBLE_FIELD(p, offset, value) \
900 write_double_field(p, offset, value)
901#endif // V8_TARGET_ARCH_MIPS
902
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000903
904#define READ_INT_FIELD(p, offset) \
905 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
906
907#define WRITE_INT_FIELD(p, offset, value) \
908 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
909
ager@chromium.org3e875802009-06-29 08:26:34 +0000910#define READ_INTPTR_FIELD(p, offset) \
911 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
912
913#define WRITE_INTPTR_FIELD(p, offset, value) \
914 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
915
ager@chromium.org7c537e22008-10-16 08:43:32 +0000916#define READ_UINT32_FIELD(p, offset) \
917 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
918
919#define WRITE_UINT32_FIELD(p, offset, value) \
920 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
921
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000922#define READ_SHORT_FIELD(p, offset) \
923 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
924
925#define WRITE_SHORT_FIELD(p, offset, value) \
926 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
927
928#define READ_BYTE_FIELD(p, offset) \
929 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
930
931#define WRITE_BYTE_FIELD(p, offset, value) \
932 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
933
934
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000935Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
936 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000937}
938
939
940int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000941 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000942}
943
944
945Smi* Smi::FromInt(int value) {
946 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000947 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000948 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000949 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000950 return reinterpret_cast<Smi*>(tagged_value);
951}
952
953
954Smi* Smi::FromIntptr(intptr_t value) {
955 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000956 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
957 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000958}
959
960
961Failure::Type Failure::type() const {
962 return static_cast<Type>(value() & kFailureTypeTagMask);
963}
964
965
966bool Failure::IsInternalError() const {
967 return type() == INTERNAL_ERROR;
968}
969
970
971bool Failure::IsOutOfMemoryException() const {
972 return type() == OUT_OF_MEMORY_EXCEPTION;
973}
974
975
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000976AllocationSpace Failure::allocation_space() const {
977 ASSERT_EQ(RETRY_AFTER_GC, type());
978 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
979 & kSpaceTagMask);
980}
981
982
983Failure* Failure::InternalError() {
984 return Construct(INTERNAL_ERROR);
985}
986
987
988Failure* Failure::Exception() {
989 return Construct(EXCEPTION);
990}
991
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000992
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000993Failure* Failure::OutOfMemoryException() {
994 return Construct(OUT_OF_MEMORY_EXCEPTION);
995}
996
997
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000998intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000999 return static_cast<intptr_t>(
1000 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001001}
1002
1003
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001004Failure* Failure::RetryAfterGC() {
1005 return RetryAfterGC(NEW_SPACE);
1006}
1007
1008
1009Failure* Failure::RetryAfterGC(AllocationSpace space) {
1010 ASSERT((space & ~kSpaceTagMask) == 0);
1011 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001012}
1013
1014
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001015Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001016 uintptr_t info =
1017 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001018 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001019 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001020}
1021
1022
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001023bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001024#ifdef DEBUG
1025 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1026#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001027
1028#ifdef V8_TARGET_ARCH_X64
1029 // To be representable as a long smi, the value must be a 32-bit integer.
1030 bool result = (value == static_cast<int32_t>(value));
1031#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001032 // To be representable as an tagged small integer, the two
1033 // most-significant bits of 'value' must be either 00 or 11 due to
1034 // sign-extension. To check this we add 01 to the two
1035 // most-significant bits, and check if the most-significant bit is 0
1036 //
1037 // CAUTION: The original code below:
1038 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1039 // may lead to incorrect results according to the C language spec, and
1040 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1041 // compiler may produce undefined results in case of signed integer
1042 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001043 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001044#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001045 ASSERT(result == in_range);
1046 return result;
1047}
1048
1049
kasper.lund7276f142008-07-30 08:49:36 +00001050MapWord MapWord::FromMap(Map* map) {
1051 return MapWord(reinterpret_cast<uintptr_t>(map));
1052}
1053
1054
1055Map* MapWord::ToMap() {
1056 return reinterpret_cast<Map*>(value_);
1057}
1058
1059
1060bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001061 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001062}
1063
1064
1065MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001066 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1067 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001068}
1069
1070
1071HeapObject* MapWord::ToForwardingAddress() {
1072 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001073 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001074}
1075
1076
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001077#ifdef DEBUG
1078void HeapObject::VerifyObjectField(int offset) {
1079 VerifyPointer(READ_FIELD(this, offset));
1080}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001081
1082void HeapObject::VerifySmiField(int offset) {
1083 ASSERT(READ_FIELD(this, offset)->IsSmi());
1084}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001085#endif
1086
1087
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001088Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001089 Heap* heap =
1090 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1091 ASSERT(heap != NULL);
1092 ASSERT(heap->isolate() == Isolate::Current());
1093 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001094}
1095
1096
1097Isolate* HeapObject::GetIsolate() {
1098 return GetHeap()->isolate();
1099}
1100
1101
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001102Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001103 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001104}
1105
1106
1107void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001108 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001109 if (value != NULL) {
1110 // TODO(1600) We are passing NULL as a slot because maps can never be on
1111 // evacuation candidate.
1112 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1113 }
1114}
1115
1116
1117// Unsafe accessor omitting write barrier.
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001118void HeapObject::set_map_no_write_barrier(Map* value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001119 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001120}
1121
1122
kasper.lund7276f142008-07-30 08:49:36 +00001123MapWord HeapObject::map_word() {
1124 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1125}
1126
1127
1128void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001129 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001130 // here.
1131 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1132}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001133
1134
1135HeapObject* HeapObject::FromAddress(Address address) {
1136 ASSERT_TAG_ALIGNED(address);
1137 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1138}
1139
1140
1141Address HeapObject::address() {
1142 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1143}
1144
1145
1146int HeapObject::Size() {
1147 return SizeFromMap(map());
1148}
1149
1150
1151void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1152 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1153 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1154}
1155
1156
1157void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1158 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1159}
1160
1161
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001162double HeapNumber::value() {
1163 return READ_DOUBLE_FIELD(this, kValueOffset);
1164}
1165
1166
1167void HeapNumber::set_value(double value) {
1168 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1169}
1170
1171
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001172int HeapNumber::get_exponent() {
1173 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1174 kExponentShift) - kExponentBias;
1175}
1176
1177
1178int HeapNumber::get_sign() {
1179 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1180}
1181
1182
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001183ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001184
1185
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001186Object** FixedArray::GetFirstElementAddress() {
1187 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1188}
1189
1190
1191bool FixedArray::ContainsOnlySmisOrHoles() {
1192 Object* the_hole = GetHeap()->the_hole_value();
1193 Object** current = GetFirstElementAddress();
1194 for (int i = 0; i < length(); ++i) {
1195 Object* candidate = *current++;
1196 if (!candidate->IsSmi() && candidate != the_hole) return false;
1197 }
1198 return true;
1199}
1200
1201
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001202FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001203 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001204 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001205}
1206
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001207void JSObject::ValidateSmiOnlyElements() {
1208#if DEBUG
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001209 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001210 Heap* heap = GetHeap();
1211 // Don't use elements, since integrity checks will fail if there
1212 // are filler pointers in the array.
1213 FixedArray* fixed_array =
1214 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
1215 Map* map = fixed_array->map();
1216 // Arrays that have been shifted in place can't be verified.
1217 if (map != heap->raw_unchecked_one_pointer_filler_map() &&
1218 map != heap->raw_unchecked_two_pointer_filler_map() &&
1219 map != heap->free_space_map()) {
1220 for (int i = 0; i < fixed_array->length(); i++) {
1221 Object* current = fixed_array->get(i);
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001222 ASSERT(current->IsSmi() || current->IsTheHole());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001223 }
1224 }
1225 }
1226#endif
1227}
1228
1229
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001230MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001231#if DEBUG
1232 ValidateSmiOnlyElements();
1233#endif
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001234 if ((map()->elements_kind() != FAST_ELEMENTS)) {
1235 return TransitionElementsKind(FAST_ELEMENTS);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001236 }
1237 return this;
1238}
1239
1240
1241MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001242 uint32_t count,
1243 EnsureElementsMode mode) {
1244 ElementsKind current_kind = map()->elements_kind();
1245 ElementsKind target_kind = current_kind;
1246 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
1247 if (current_kind == FAST_ELEMENTS) return this;
1248
1249 Heap* heap = GetHeap();
1250 Object* the_hole = heap->the_hole_value();
1251 Object* heap_number_map = heap->heap_number_map();
1252 for (uint32_t i = 0; i < count; ++i) {
1253 Object* current = *objects++;
1254 if (!current->IsSmi() && current != the_hole) {
1255 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS &&
1256 HeapObject::cast(current)->map() == heap_number_map) {
1257 target_kind = FAST_DOUBLE_ELEMENTS;
1258 } else {
1259 target_kind = FAST_ELEMENTS;
1260 break;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001261 }
1262 }
1263 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001264
1265 if (target_kind != current_kind) {
1266 return TransitionElementsKind(target_kind);
1267 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001268 return this;
1269}
1270
1271
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001272MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
1273 EnsureElementsMode mode) {
1274 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1275 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1276 elements->map() == GetHeap()->fixed_cow_array_map());
1277 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1278 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1279 }
1280 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
1281 return EnsureCanContainElements(objects, elements->length(), mode);
1282 }
1283
1284 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
1285 if (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) {
1286 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1287 }
1288
1289 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001290}
1291
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001292
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001293void JSObject::set_map_and_elements(Map* new_map,
1294 FixedArrayBase* value,
1295 WriteBarrierMode mode) {
1296 ASSERT(value->HasValidElements());
1297#ifdef DEBUG
1298 ValidateSmiOnlyElements();
1299#endif
1300 if (new_map != NULL) {
1301 if (mode == UPDATE_WRITE_BARRIER) {
1302 set_map(new_map);
1303 } else {
1304 ASSERT(mode == SKIP_WRITE_BARRIER);
1305 set_map_no_write_barrier(new_map);
1306 }
1307 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001308 ASSERT((map()->has_fast_elements() ||
1309 map()->has_fast_smi_only_elements()) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001310 (value->map() == GetHeap()->fixed_array_map() ||
1311 value->map() == GetHeap()->fixed_cow_array_map()));
lrn@chromium.orgd4e9e222011-08-03 12:01:58 +00001312 ASSERT(map()->has_fast_double_elements() ==
1313 value->IsFixedDoubleArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001314 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001315 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001316}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001317
1318
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001319void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1320 set_map_and_elements(NULL, value, mode);
1321}
1322
1323
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001324void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001325 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1326 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001327}
1328
1329
1330void JSObject::initialize_elements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001331 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001332 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1333 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001334}
1335
1336
lrn@chromium.org303ada72010-10-27 09:33:13 +00001337MaybeObject* JSObject::ResetElements() {
1338 Object* obj;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001339 ElementsKind elements_kind = FLAG_smi_only_arrays
1340 ? FAST_SMI_ONLY_ELEMENTS
1341 : FAST_ELEMENTS;
1342 MaybeObject* maybe_obj = GetElementsTransitionMap(elements_kind);
1343 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001344 set_map(Map::cast(obj));
1345 initialize_elements();
1346 return this;
1347}
1348
1349
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001350ACCESSORS(Oddball, to_string, String, kToStringOffset)
1351ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1352
1353
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001354byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001355 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001356}
1357
1358
1359void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001360 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001361}
1362
1363
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001364Object* JSGlobalPropertyCell::value() {
1365 return READ_FIELD(this, kValueOffset);
1366}
1367
1368
1369void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1370 // The write barrier is not used for global property cells.
1371 ASSERT(!val->IsJSGlobalPropertyCell());
1372 WRITE_FIELD(this, kValueOffset, val);
1373}
1374
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001375
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001376int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001377 InstanceType type = map()->instance_type();
1378 // Check for the most common kind of JavaScript object before
1379 // falling into the generic switch. This speeds up the internal
1380 // field operations considerably on average.
1381 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1382 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001383 case JS_GLOBAL_PROXY_TYPE:
1384 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001385 case JS_GLOBAL_OBJECT_TYPE:
1386 return JSGlobalObject::kSize;
1387 case JS_BUILTINS_OBJECT_TYPE:
1388 return JSBuiltinsObject::kSize;
1389 case JS_FUNCTION_TYPE:
1390 return JSFunction::kSize;
1391 case JS_VALUE_TYPE:
1392 return JSValue::kSize;
1393 case JS_ARRAY_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001394 return JSArray::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001395 case JS_WEAK_MAP_TYPE:
1396 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001397 case JS_REGEXP_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001398 return JSRegExp::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001399 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001400 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001401 case JS_MESSAGE_OBJECT_TYPE:
1402 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001403 default:
1404 UNREACHABLE();
1405 return 0;
1406 }
1407}
1408
1409
1410int JSObject::GetInternalFieldCount() {
1411 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001412 // Make sure to adjust for the number of in-object properties. These
1413 // properties do contribute to the size, but are not internal fields.
1414 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1415 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001416}
1417
1418
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001419int JSObject::GetInternalFieldOffset(int index) {
1420 ASSERT(index < GetInternalFieldCount() && index >= 0);
1421 return GetHeaderSize() + (kPointerSize * index);
1422}
1423
1424
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001425Object* JSObject::GetInternalField(int index) {
1426 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001427 // Internal objects do follow immediately after the header, whereas in-object
1428 // properties are at the end of the object. Therefore there is no need
1429 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001430 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1431}
1432
1433
1434void JSObject::SetInternalField(int index, Object* value) {
1435 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001436 // Internal objects do follow immediately after the header, whereas in-object
1437 // properties are at the end of the object. Therefore there is no need
1438 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001439 int offset = GetHeaderSize() + (kPointerSize * index);
1440 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001441 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001442}
1443
1444
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001445void JSObject::SetInternalField(int index, Smi* value) {
1446 ASSERT(index < GetInternalFieldCount() && index >= 0);
1447 // Internal objects do follow immediately after the header, whereas in-object
1448 // properties are at the end of the object. Therefore there is no need
1449 // to adjust the index here.
1450 int offset = GetHeaderSize() + (kPointerSize * index);
1451 WRITE_FIELD(this, offset, value);
1452}
1453
1454
ager@chromium.org7c537e22008-10-16 08:43:32 +00001455// Access fast-case object properties at index. The use of these routines
1456// is needed to correctly distinguish between properties stored in-object and
1457// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001458Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001459 // Adjust for the number of properties stored in the object.
1460 index -= map()->inobject_properties();
1461 if (index < 0) {
1462 int offset = map()->instance_size() + (index * kPointerSize);
1463 return READ_FIELD(this, offset);
1464 } else {
1465 ASSERT(index < properties()->length());
1466 return properties()->get(index);
1467 }
1468}
1469
1470
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001471Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001472 // Adjust for the number of properties stored in the object.
1473 index -= map()->inobject_properties();
1474 if (index < 0) {
1475 int offset = map()->instance_size() + (index * kPointerSize);
1476 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001477 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001478 } else {
1479 ASSERT(index < properties()->length());
1480 properties()->set(index, value);
1481 }
1482 return value;
1483}
1484
1485
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001486int JSObject::GetInObjectPropertyOffset(int index) {
1487 // Adjust for the number of properties stored in the object.
1488 index -= map()->inobject_properties();
1489 ASSERT(index < 0);
1490 return map()->instance_size() + (index * kPointerSize);
1491}
1492
1493
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001494Object* JSObject::InObjectPropertyAt(int index) {
1495 // Adjust for the number of properties stored in the object.
1496 index -= map()->inobject_properties();
1497 ASSERT(index < 0);
1498 int offset = map()->instance_size() + (index * kPointerSize);
1499 return READ_FIELD(this, offset);
1500}
1501
1502
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001503Object* JSObject::InObjectPropertyAtPut(int index,
1504 Object* value,
1505 WriteBarrierMode mode) {
1506 // Adjust for the number of properties stored in the object.
1507 index -= map()->inobject_properties();
1508 ASSERT(index < 0);
1509 int offset = map()->instance_size() + (index * kPointerSize);
1510 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001511 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001512 return value;
1513}
1514
1515
1516
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001517void JSObject::InitializeBody(Map* map,
1518 Object* pre_allocated_value,
1519 Object* filler_value) {
1520 ASSERT(!filler_value->IsHeapObject() ||
1521 !GetHeap()->InNewSpace(filler_value));
1522 ASSERT(!pre_allocated_value->IsHeapObject() ||
1523 !GetHeap()->InNewSpace(pre_allocated_value));
1524 int size = map->instance_size();
1525 int offset = kHeaderSize;
1526 if (filler_value != pre_allocated_value) {
1527 int pre_allocated = map->pre_allocated_property_fields();
1528 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1529 for (int i = 0; i < pre_allocated; i++) {
1530 WRITE_FIELD(this, offset, pre_allocated_value);
1531 offset += kPointerSize;
1532 }
1533 }
1534 while (offset < size) {
1535 WRITE_FIELD(this, offset, filler_value);
1536 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001537 }
1538}
1539
1540
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001541bool JSObject::HasFastProperties() {
1542 return !properties()->IsDictionary();
1543}
1544
1545
1546int JSObject::MaxFastProperties() {
1547 // Allow extra fast properties if the object has more than
1548 // kMaxFastProperties in-object properties. When this is the case,
1549 // it is very unlikely that the object is being used as a dictionary
1550 // and there is a good chance that allowing more map transitions
1551 // will be worth it.
1552 return Max(map()->inobject_properties(), kMaxFastProperties);
1553}
1554
1555
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001556void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001557 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001558 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001559 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001560 }
1561}
1562
1563
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001564bool Object::ToArrayIndex(uint32_t* index) {
1565 if (IsSmi()) {
1566 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001567 if (value < 0) return false;
1568 *index = value;
1569 return true;
1570 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001571 if (IsHeapNumber()) {
1572 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001573 uint32_t uint_value = static_cast<uint32_t>(value);
1574 if (value == static_cast<double>(uint_value)) {
1575 *index = uint_value;
1576 return true;
1577 }
1578 }
1579 return false;
1580}
1581
1582
1583bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1584 if (!this->IsJSValue()) return false;
1585
1586 JSValue* js_value = JSValue::cast(this);
1587 if (!js_value->value()->IsString()) return false;
1588
1589 String* str = String::cast(js_value->value());
1590 if (index >= (uint32_t)str->length()) return false;
1591
1592 return true;
1593}
1594
1595
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001596FixedArrayBase* FixedArrayBase::cast(Object* object) {
1597 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1598 return reinterpret_cast<FixedArrayBase*>(object);
1599}
1600
1601
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001602Object* FixedArray::get(int index) {
1603 ASSERT(index >= 0 && index < this->length());
1604 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1605}
1606
1607
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001608void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001609 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001610 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001611 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1612 int offset = kHeaderSize + index * kPointerSize;
1613 WRITE_FIELD(this, offset, value);
1614}
1615
1616
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001617void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001618 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001619 ASSERT(index >= 0 && index < this->length());
1620 int offset = kHeaderSize + index * kPointerSize;
1621 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001622 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001623}
1624
1625
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001626inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1627 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1628}
1629
1630
1631inline double FixedDoubleArray::hole_nan_as_double() {
1632 return BitCast<double, uint64_t>(kHoleNanInt64);
1633}
1634
1635
1636inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1637 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1638 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1639 return OS::nan_value();
1640}
1641
1642
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001643double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001644 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1645 map() != HEAP->fixed_array_map());
1646 ASSERT(index >= 0 && index < this->length());
1647 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1648 ASSERT(!is_the_hole_nan(result));
1649 return result;
1650}
1651
1652
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001653MaybeObject* FixedDoubleArray::get(int index) {
1654 if (is_the_hole(index)) {
1655 return GetHeap()->the_hole_value();
1656 } else {
1657 return GetHeap()->NumberFromDouble(get_scalar(index));
1658 }
1659}
1660
1661
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001662void FixedDoubleArray::set(int index, double value) {
1663 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1664 map() != HEAP->fixed_array_map());
1665 int offset = kHeaderSize + index * kDoubleSize;
1666 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1667 WRITE_DOUBLE_FIELD(this, offset, value);
1668}
1669
1670
1671void FixedDoubleArray::set_the_hole(int index) {
1672 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1673 map() != HEAP->fixed_array_map());
1674 int offset = kHeaderSize + index * kDoubleSize;
1675 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1676}
1677
1678
1679bool FixedDoubleArray::is_the_hole(int index) {
1680 int offset = kHeaderSize + index * kDoubleSize;
1681 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1682}
1683
1684
1685void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1686 int old_length = from->length();
1687 ASSERT(old_length < length());
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001688 if (old_length * kDoubleSize >= OS::kMinComplexMemCopy) {
1689 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1690 FIELD_ADDR(from, kHeaderSize),
1691 old_length * kDoubleSize);
1692 } else {
1693 for (int i = 0; i < old_length; ++i) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001694 if (from->is_the_hole(i)) {
1695 set_the_hole(i);
1696 } else {
1697 set(i, from->get_scalar(i));
1698 }
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001699 }
1700 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001701 int offset = kHeaderSize + old_length * kDoubleSize;
1702 for (int current = from->length(); current < length(); ++current) {
1703 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1704 offset += kDoubleSize;
1705 }
1706}
1707
1708
1709void FixedDoubleArray::Initialize(FixedArray* from) {
1710 int old_length = from->length();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001711 ASSERT(old_length <= length());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001712 for (int i = 0; i < old_length; i++) {
1713 Object* hole_or_object = from->get(i);
1714 if (hole_or_object->IsTheHole()) {
1715 set_the_hole(i);
1716 } else {
1717 set(i, hole_or_object->Number());
1718 }
1719 }
1720 int offset = kHeaderSize + old_length * kDoubleSize;
1721 for (int current = from->length(); current < length(); ++current) {
1722 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1723 offset += kDoubleSize;
1724 }
1725}
1726
1727
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001728void FixedDoubleArray::Initialize(SeededNumberDictionary* from) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001729 int offset = kHeaderSize;
1730 for (int current = 0; current < length(); ++current) {
1731 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1732 offset += kDoubleSize;
1733 }
1734 for (int i = 0; i < from->Capacity(); i++) {
1735 Object* key = from->KeyAt(i);
1736 if (key->IsNumber()) {
1737 uint32_t entry = static_cast<uint32_t>(key->Number());
1738 set(entry, from->ValueAt(i)->Number());
1739 }
1740 }
1741}
1742
1743
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001744WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001745 Heap* heap = GetHeap();
1746 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1747 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001748 return UPDATE_WRITE_BARRIER;
1749}
1750
1751
1752void FixedArray::set(int index,
1753 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001754 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001755 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001756 ASSERT(index >= 0 && index < this->length());
1757 int offset = kHeaderSize + index * kPointerSize;
1758 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001759 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001760}
1761
1762
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001763void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1764 int index,
1765 Object* value) {
1766 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
1767 ASSERT(index >= 0 && index < array->length());
1768 int offset = kHeaderSize + index * kPointerSize;
1769 WRITE_FIELD(array, offset, value);
1770 Heap* heap = array->GetHeap();
1771 if (heap->InNewSpace(value)) {
1772 heap->RecordWrite(array->address(), offset);
1773 }
1774}
1775
1776
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001777void FixedArray::NoWriteBarrierSet(FixedArray* array,
1778 int index,
1779 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001780 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001781 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001782 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001783 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1784}
1785
1786
1787void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001788 ASSERT(map() != HEAP->fixed_cow_array_map());
1789 set_undefined(GetHeap(), index);
1790}
1791
1792
1793void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001794 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001795 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001796 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001797 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001798}
1799
1800
ager@chromium.org236ad962008-09-25 09:45:57 +00001801void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001802 set_null(GetHeap(), index);
1803}
1804
1805
1806void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001807 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001808 ASSERT(!heap->InNewSpace(heap->null_value()));
1809 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001810}
1811
1812
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001813void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001814 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001815 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001816 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1817 WRITE_FIELD(this,
1818 kHeaderSize + index * kPointerSize,
1819 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001820}
1821
1822
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001823void FixedArray::set_unchecked(int index, Smi* value) {
1824 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1825 int offset = kHeaderSize + index * kPointerSize;
1826 WRITE_FIELD(this, offset, value);
1827}
1828
1829
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001830void FixedArray::set_unchecked(Heap* heap,
1831 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001832 Object* value,
1833 WriteBarrierMode mode) {
1834 int offset = kHeaderSize + index * kPointerSize;
1835 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001836 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001837}
1838
1839
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001840void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001841 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001842 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1843 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001844}
1845
1846
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001847Object** FixedArray::data_start() {
1848 return HeapObject::RawField(this, kHeaderSize);
1849}
1850
1851
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001852bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001853 ASSERT(this->IsSmi() ||
1854 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001855 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001856 return this->IsSmi() || length() <= kFirstIndex;
1857}
1858
1859
1860int DescriptorArray::bit_field3_storage() {
1861 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1862 return Smi::cast(storage)->value();
1863}
1864
1865void DescriptorArray::set_bit_field3_storage(int value) {
1866 ASSERT(!IsEmpty());
1867 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001868}
1869
1870
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001871void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1872 int first,
1873 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001874 Object* tmp = array->get(first);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001875 NoIncrementalWriteBarrierSet(array, first, array->get(second));
1876 NoIncrementalWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001877}
1878
1879
1880int DescriptorArray::Search(String* name) {
1881 SLOW_ASSERT(IsSortedNoDuplicates());
1882
1883 // Check for empty descriptor array.
1884 int nof = number_of_descriptors();
1885 if (nof == 0) return kNotFound;
1886
1887 // Fast case: do linear search for small arrays.
1888 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001889 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001890 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001891 }
1892
1893 // Slow case: perform binary search.
1894 return BinarySearch(name, 0, nof - 1);
1895}
1896
1897
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001898int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001899 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001900 if (number == DescriptorLookupCache::kAbsent) {
1901 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001902 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001903 }
1904 return number;
1905}
1906
1907
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001908String* DescriptorArray::GetKey(int descriptor_number) {
1909 ASSERT(descriptor_number < number_of_descriptors());
1910 return String::cast(get(ToKeyIndex(descriptor_number)));
1911}
1912
1913
1914Object* DescriptorArray::GetValue(int descriptor_number) {
1915 ASSERT(descriptor_number < number_of_descriptors());
1916 return GetContentArray()->get(ToValueIndex(descriptor_number));
1917}
1918
1919
1920Smi* DescriptorArray::GetDetails(int descriptor_number) {
1921 ASSERT(descriptor_number < number_of_descriptors());
1922 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1923}
1924
1925
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001926PropertyType DescriptorArray::GetType(int descriptor_number) {
1927 ASSERT(descriptor_number < number_of_descriptors());
1928 return PropertyDetails(GetDetails(descriptor_number)).type();
1929}
1930
1931
1932int DescriptorArray::GetFieldIndex(int descriptor_number) {
1933 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1934}
1935
1936
1937JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1938 return JSFunction::cast(GetValue(descriptor_number));
1939}
1940
1941
1942Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1943 ASSERT(GetType(descriptor_number) == CALLBACKS);
1944 return GetValue(descriptor_number);
1945}
1946
1947
1948AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1949 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001950 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001951 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001952}
1953
1954
1955bool DescriptorArray::IsProperty(int descriptor_number) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001956 return IsRealProperty(GetType(descriptor_number));
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001957}
1958
1959
1960bool DescriptorArray::IsTransition(int descriptor_number) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001961 return IsTransitionType(GetType(descriptor_number));
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001962}
1963
1964
1965bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1966 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1967}
1968
1969
1970bool DescriptorArray::IsDontEnum(int descriptor_number) {
1971 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1972}
1973
1974
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001975void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1976 desc->Init(GetKey(descriptor_number),
1977 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001978 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001979}
1980
1981
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001982void DescriptorArray::Set(int descriptor_number,
1983 Descriptor* desc,
1984 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001985 // Range check.
1986 ASSERT(descriptor_number < number_of_descriptors());
1987
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001988 NoIncrementalWriteBarrierSet(this,
1989 ToKeyIndex(descriptor_number),
1990 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001991 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001992 NoIncrementalWriteBarrierSet(content_array,
1993 ToValueIndex(descriptor_number),
1994 desc->GetValue());
1995 NoIncrementalWriteBarrierSet(content_array,
1996 ToDetailsIndex(descriptor_number),
1997 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001998}
1999
2000
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002001void DescriptorArray::CopyFrom(int index,
2002 DescriptorArray* src,
2003 int src_index,
2004 const WhitenessWitness& witness) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002005 Descriptor desc;
2006 src->Get(src_index, &desc);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002007 Set(index, &desc, witness);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002008}
2009
2010
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002011void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2012 int first, int second) {
2013 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002014 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002015 NoIncrementalWriteBarrierSwap(content_array,
2016 ToValueIndex(first),
2017 ToValueIndex(second));
2018 NoIncrementalWriteBarrierSwap(content_array,
2019 ToDetailsIndex(first),
2020 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002021}
2022
2023
2024DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
2025 : marking_(array->GetHeap()->incremental_marking()) {
2026 marking_->EnterNoMarkingScope();
2027 if (array->number_of_descriptors() > 0) {
2028 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
2029 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
2030 }
2031}
2032
2033
2034DescriptorArray::WhitenessWitness::~WhitenessWitness() {
2035 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002036}
2037
2038
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002039template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002040int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2041 const int kMinCapacity = 32;
2042 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2043 if (capacity < kMinCapacity) {
2044 capacity = kMinCapacity; // Guarantee min capacity.
2045 }
2046 return capacity;
2047}
2048
2049
2050template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002051int HashTable<Shape, Key>::FindEntry(Key key) {
2052 return FindEntry(GetIsolate(), key);
2053}
2054
2055
2056// Find entry for key otherwise return kNotFound.
2057template<typename Shape, typename Key>
2058int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2059 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002060 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002061 uint32_t count = 1;
2062 // EnsureCapacity will guarantee the hash table is never full.
2063 while (true) {
2064 Object* element = KeyAt(entry);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002065 // Empty entry.
2066 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2067 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002068 Shape::IsMatch(key, element)) return entry;
2069 entry = NextProbe(entry, count++, capacity);
2070 }
2071 return kNotFound;
2072}
2073
2074
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002075bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002076 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002077 if (!max_index_object->IsSmi()) return false;
2078 return 0 !=
2079 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2080}
2081
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002082uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002083 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002084 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002085 if (!max_index_object->IsSmi()) return 0;
2086 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2087 return value >> kRequiresSlowElementsTagSize;
2088}
2089
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002090void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002091 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002092}
2093
2094
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002095// ------------------------------------
2096// Cast operations
2097
2098
2099CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002100CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002101CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002102CAST_ACCESSOR(DeoptimizationInputData)
2103CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002104CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002105CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002106CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002107CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002108CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002109CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002110CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002111CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002112CAST_ACCESSOR(String)
2113CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002114CAST_ACCESSOR(SeqAsciiString)
2115CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002116CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002117CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002118CAST_ACCESSOR(ExternalString)
2119CAST_ACCESSOR(ExternalAsciiString)
2120CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002121CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002122CAST_ACCESSOR(JSObject)
2123CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002124CAST_ACCESSOR(HeapObject)
2125CAST_ACCESSOR(HeapNumber)
2126CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002127CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002128CAST_ACCESSOR(SharedFunctionInfo)
2129CAST_ACCESSOR(Map)
2130CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002131CAST_ACCESSOR(GlobalObject)
2132CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002133CAST_ACCESSOR(JSGlobalObject)
2134CAST_ACCESSOR(JSBuiltinsObject)
2135CAST_ACCESSOR(Code)
2136CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002137CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002138CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002139CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002140CAST_ACCESSOR(JSSet)
2141CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002142CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002143CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002144CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002145CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002146CAST_ACCESSOR(ExternalArray)
2147CAST_ACCESSOR(ExternalByteArray)
2148CAST_ACCESSOR(ExternalUnsignedByteArray)
2149CAST_ACCESSOR(ExternalShortArray)
2150CAST_ACCESSOR(ExternalUnsignedShortArray)
2151CAST_ACCESSOR(ExternalIntArray)
2152CAST_ACCESSOR(ExternalUnsignedIntArray)
2153CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002154CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002155CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002156CAST_ACCESSOR(Struct)
2157
2158
2159#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2160 STRUCT_LIST(MAKE_STRUCT_CAST)
2161#undef MAKE_STRUCT_CAST
2162
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002163
2164template <typename Shape, typename Key>
2165HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002166 ASSERT(obj->IsHashTable());
2167 return reinterpret_cast<HashTable*>(obj);
2168}
2169
2170
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002171SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002172SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002173
ager@chromium.orgac091b72010-05-05 07:34:42 +00002174SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002175
2176
2177uint32_t String::hash_field() {
2178 return READ_UINT32_FIELD(this, kHashFieldOffset);
2179}
2180
2181
2182void String::set_hash_field(uint32_t value) {
2183 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002184#if V8_HOST_ARCH_64_BIT
2185 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2186#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002187}
2188
2189
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002190bool String::Equals(String* other) {
2191 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002192 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2193 return false;
2194 }
2195 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002196}
2197
2198
lrn@chromium.org303ada72010-10-27 09:33:13 +00002199MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002200 if (!StringShape(this).IsCons()) return this;
2201 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002202 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002203 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002204}
2205
2206
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002207String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002208 MaybeObject* flat = TryFlatten(pretenure);
2209 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002210 if (!flat->ToObject(&successfully_flattened)) return this;
2211 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002212}
2213
2214
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002215uint16_t String::Get(int index) {
2216 ASSERT(index >= 0 && index < length());
2217 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002218 case kSeqStringTag | kAsciiStringTag:
2219 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2220 case kSeqStringTag | kTwoByteStringTag:
2221 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2222 case kConsStringTag | kAsciiStringTag:
2223 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002224 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002225 case kExternalStringTag | kAsciiStringTag:
2226 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2227 case kExternalStringTag | kTwoByteStringTag:
2228 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002229 case kSlicedStringTag | kAsciiStringTag:
2230 case kSlicedStringTag | kTwoByteStringTag:
2231 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002232 default:
2233 break;
2234 }
2235
2236 UNREACHABLE();
2237 return 0;
2238}
2239
2240
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002241void String::Set(int index, uint16_t value) {
2242 ASSERT(index >= 0 && index < length());
2243 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002244
ager@chromium.org5ec48922009-05-05 07:25:34 +00002245 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002246 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2247 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002248}
2249
2250
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002251bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002252 if (!StringShape(this).IsCons()) return true;
2253 return ConsString::cast(this)->second()->length() == 0;
2254}
2255
2256
2257String* String::GetUnderlying() {
2258 // Giving direct access to underlying string only makes sense if the
2259 // wrapping string is already flattened.
2260 ASSERT(this->IsFlat());
2261 ASSERT(StringShape(this).IsIndirect());
2262 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2263 const int kUnderlyingOffset = SlicedString::kParentOffset;
2264 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002265}
2266
2267
ager@chromium.org7c537e22008-10-16 08:43:32 +00002268uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002269 ASSERT(index >= 0 && index < length());
2270 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2271}
2272
2273
ager@chromium.org7c537e22008-10-16 08:43:32 +00002274void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002275 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2276 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2277 static_cast<byte>(value));
2278}
2279
2280
ager@chromium.org7c537e22008-10-16 08:43:32 +00002281Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002282 return FIELD_ADDR(this, kHeaderSize);
2283}
2284
2285
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002286char* SeqAsciiString::GetChars() {
2287 return reinterpret_cast<char*>(GetCharsAddress());
2288}
2289
2290
ager@chromium.org7c537e22008-10-16 08:43:32 +00002291Address SeqTwoByteString::GetCharsAddress() {
2292 return FIELD_ADDR(this, kHeaderSize);
2293}
2294
2295
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002296uc16* SeqTwoByteString::GetChars() {
2297 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2298}
2299
2300
ager@chromium.org7c537e22008-10-16 08:43:32 +00002301uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002302 ASSERT(index >= 0 && index < length());
2303 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2304}
2305
2306
ager@chromium.org7c537e22008-10-16 08:43:32 +00002307void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002308 ASSERT(index >= 0 && index < length());
2309 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2310}
2311
2312
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002313int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002314 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002315}
2316
2317
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002318int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002319 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002320}
2321
2322
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002323String* SlicedString::parent() {
2324 return String::cast(READ_FIELD(this, kParentOffset));
2325}
2326
2327
2328void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002329 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002330 WRITE_FIELD(this, kParentOffset, parent);
2331}
2332
2333
2334SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2335
2336
ager@chromium.org870a0b62008-11-04 11:43:05 +00002337String* ConsString::first() {
2338 return String::cast(READ_FIELD(this, kFirstOffset));
2339}
2340
2341
2342Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002343 return READ_FIELD(this, kFirstOffset);
2344}
2345
2346
ager@chromium.org870a0b62008-11-04 11:43:05 +00002347void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002348 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002349 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002350}
2351
2352
ager@chromium.org870a0b62008-11-04 11:43:05 +00002353String* ConsString::second() {
2354 return String::cast(READ_FIELD(this, kSecondOffset));
2355}
2356
2357
2358Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002359 return READ_FIELD(this, kSecondOffset);
2360}
2361
2362
ager@chromium.org870a0b62008-11-04 11:43:05 +00002363void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002364 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002365 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002366}
2367
2368
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002369bool ExternalString::is_short() {
2370 InstanceType type = map()->instance_type();
2371 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002372}
2373
2374
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002375const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002376 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2377}
2378
2379
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002380void ExternalAsciiString::update_data_cache() {
2381 if (is_short()) return;
2382 const char** data_field =
2383 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2384 *data_field = resource()->data();
2385}
2386
2387
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002388void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002389 const ExternalAsciiString::Resource* resource) {
2390 *reinterpret_cast<const Resource**>(
2391 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002392 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002393}
2394
2395
2396const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002397 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002398}
2399
2400
2401uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2402 ASSERT(index >= 0 && index < length());
2403 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002404}
2405
2406
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002407const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002408 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2409}
2410
2411
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002412void ExternalTwoByteString::update_data_cache() {
2413 if (is_short()) return;
2414 const uint16_t** data_field =
2415 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2416 *data_field = resource()->data();
2417}
2418
2419
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002420void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002421 const ExternalTwoByteString::Resource* resource) {
2422 *reinterpret_cast<const Resource**>(
2423 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002424 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002425}
2426
2427
2428const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002429 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002430}
2431
2432
2433uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2434 ASSERT(index >= 0 && index < length());
2435 return GetChars()[index];
2436}
2437
2438
2439const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2440 unsigned start) {
2441 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002442}
2443
2444
ager@chromium.orgac091b72010-05-05 07:34:42 +00002445void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002446 set_finger_index(kEntriesIndex);
2447 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002448}
2449
2450
2451void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002452 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002453 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002454 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002455 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002456 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002457 MakeZeroSize();
2458}
2459
2460
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002461int JSFunctionResultCache::size() {
2462 return Smi::cast(get(kCacheSizeIndex))->value();
2463}
2464
2465
2466void JSFunctionResultCache::set_size(int size) {
2467 set(kCacheSizeIndex, Smi::FromInt(size));
2468}
2469
2470
2471int JSFunctionResultCache::finger_index() {
2472 return Smi::cast(get(kFingerIndex))->value();
2473}
2474
2475
2476void JSFunctionResultCache::set_finger_index(int finger_index) {
2477 set(kFingerIndex, Smi::FromInt(finger_index));
2478}
2479
2480
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002481byte ByteArray::get(int index) {
2482 ASSERT(index >= 0 && index < this->length());
2483 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2484}
2485
2486
2487void ByteArray::set(int index, byte value) {
2488 ASSERT(index >= 0 && index < this->length());
2489 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2490}
2491
2492
2493int ByteArray::get_int(int index) {
2494 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2495 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2496}
2497
2498
2499ByteArray* ByteArray::FromDataStartAddress(Address address) {
2500 ASSERT_TAG_ALIGNED(address);
2501 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2502}
2503
2504
2505Address ByteArray::GetDataStartAddress() {
2506 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2507}
2508
2509
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002510uint8_t* ExternalPixelArray::external_pixel_pointer() {
2511 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002512}
2513
2514
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002515uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002516 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002517 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002518 return ptr[index];
2519}
2520
2521
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002522MaybeObject* ExternalPixelArray::get(int index) {
2523 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2524}
2525
2526
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002527void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002528 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002529 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002530 ptr[index] = value;
2531}
2532
2533
ager@chromium.org3811b432009-10-28 14:53:37 +00002534void* ExternalArray::external_pointer() {
2535 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2536 return reinterpret_cast<void*>(ptr);
2537}
2538
2539
2540void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2541 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2542 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2543}
2544
2545
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002546int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002547 ASSERT((index >= 0) && (index < this->length()));
2548 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2549 return ptr[index];
2550}
2551
2552
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002553MaybeObject* ExternalByteArray::get(int index) {
2554 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2555}
2556
2557
ager@chromium.org3811b432009-10-28 14:53:37 +00002558void ExternalByteArray::set(int index, int8_t value) {
2559 ASSERT((index >= 0) && (index < this->length()));
2560 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2561 ptr[index] = value;
2562}
2563
2564
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002565uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002566 ASSERT((index >= 0) && (index < this->length()));
2567 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2568 return ptr[index];
2569}
2570
2571
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002572MaybeObject* ExternalUnsignedByteArray::get(int index) {
2573 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2574}
2575
2576
ager@chromium.org3811b432009-10-28 14:53:37 +00002577void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2578 ASSERT((index >= 0) && (index < this->length()));
2579 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2580 ptr[index] = value;
2581}
2582
2583
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002584int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002585 ASSERT((index >= 0) && (index < this->length()));
2586 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2587 return ptr[index];
2588}
2589
2590
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002591MaybeObject* ExternalShortArray::get(int index) {
2592 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2593}
2594
2595
ager@chromium.org3811b432009-10-28 14:53:37 +00002596void ExternalShortArray::set(int index, int16_t value) {
2597 ASSERT((index >= 0) && (index < this->length()));
2598 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2599 ptr[index] = value;
2600}
2601
2602
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002603uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002604 ASSERT((index >= 0) && (index < this->length()));
2605 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2606 return ptr[index];
2607}
2608
2609
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002610MaybeObject* ExternalUnsignedShortArray::get(int index) {
2611 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2612}
2613
2614
ager@chromium.org3811b432009-10-28 14:53:37 +00002615void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2616 ASSERT((index >= 0) && (index < this->length()));
2617 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2618 ptr[index] = value;
2619}
2620
2621
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002622int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002623 ASSERT((index >= 0) && (index < this->length()));
2624 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2625 return ptr[index];
2626}
2627
2628
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002629MaybeObject* ExternalIntArray::get(int index) {
2630 return GetHeap()->NumberFromInt32(get_scalar(index));
2631}
2632
2633
ager@chromium.org3811b432009-10-28 14:53:37 +00002634void ExternalIntArray::set(int index, int32_t value) {
2635 ASSERT((index >= 0) && (index < this->length()));
2636 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2637 ptr[index] = value;
2638}
2639
2640
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002641uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002642 ASSERT((index >= 0) && (index < this->length()));
2643 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2644 return ptr[index];
2645}
2646
2647
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002648MaybeObject* ExternalUnsignedIntArray::get(int index) {
2649 return GetHeap()->NumberFromUint32(get_scalar(index));
2650}
2651
2652
ager@chromium.org3811b432009-10-28 14:53:37 +00002653void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2654 ASSERT((index >= 0) && (index < this->length()));
2655 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2656 ptr[index] = value;
2657}
2658
2659
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002660float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002661 ASSERT((index >= 0) && (index < this->length()));
2662 float* ptr = static_cast<float*>(external_pointer());
2663 return ptr[index];
2664}
2665
2666
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002667MaybeObject* ExternalFloatArray::get(int index) {
2668 return GetHeap()->NumberFromDouble(get_scalar(index));
2669}
2670
2671
ager@chromium.org3811b432009-10-28 14:53:37 +00002672void ExternalFloatArray::set(int index, float value) {
2673 ASSERT((index >= 0) && (index < this->length()));
2674 float* ptr = static_cast<float*>(external_pointer());
2675 ptr[index] = value;
2676}
2677
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002678
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002679double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002680 ASSERT((index >= 0) && (index < this->length()));
2681 double* ptr = static_cast<double*>(external_pointer());
2682 return ptr[index];
2683}
2684
2685
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002686MaybeObject* ExternalDoubleArray::get(int index) {
2687 return GetHeap()->NumberFromDouble(get_scalar(index));
2688}
2689
2690
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002691void ExternalDoubleArray::set(int index, double value) {
2692 ASSERT((index >= 0) && (index < this->length()));
2693 double* ptr = static_cast<double*>(external_pointer());
2694 ptr[index] = value;
2695}
2696
2697
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002698int Map::visitor_id() {
2699 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2700}
2701
2702
2703void Map::set_visitor_id(int id) {
2704 ASSERT(0 <= id && id < 256);
2705 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2706}
2707
ager@chromium.org3811b432009-10-28 14:53:37 +00002708
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002709int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002710 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2711}
2712
2713
2714int Map::inobject_properties() {
2715 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002716}
2717
2718
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002719int Map::pre_allocated_property_fields() {
2720 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2721}
2722
2723
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002724int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002725 int instance_size = map->instance_size();
2726 if (instance_size != kVariableSizeSentinel) return instance_size;
2727 // We can ignore the "symbol" bit becase it is only set for symbols
2728 // and implies a string type.
2729 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002730 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002731 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002732 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002733 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002734 if (instance_type == ASCII_STRING_TYPE) {
2735 return SeqAsciiString::SizeFor(
2736 reinterpret_cast<SeqAsciiString*>(this)->length());
2737 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002738 if (instance_type == BYTE_ARRAY_TYPE) {
2739 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2740 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002741 if (instance_type == FREE_SPACE_TYPE) {
2742 return reinterpret_cast<FreeSpace*>(this)->size();
2743 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002744 if (instance_type == STRING_TYPE) {
2745 return SeqTwoByteString::SizeFor(
2746 reinterpret_cast<SeqTwoByteString*>(this)->length());
2747 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002748 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2749 return FixedDoubleArray::SizeFor(
2750 reinterpret_cast<FixedDoubleArray*>(this)->length());
2751 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002752 ASSERT(instance_type == CODE_TYPE);
2753 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002754}
2755
2756
2757void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002758 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002759 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002760 ASSERT(0 <= value && value < 256);
2761 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2762}
2763
2764
ager@chromium.org7c537e22008-10-16 08:43:32 +00002765void Map::set_inobject_properties(int value) {
2766 ASSERT(0 <= value && value < 256);
2767 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2768}
2769
2770
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002771void Map::set_pre_allocated_property_fields(int value) {
2772 ASSERT(0 <= value && value < 256);
2773 WRITE_BYTE_FIELD(this,
2774 kPreAllocatedPropertyFieldsOffset,
2775 static_cast<byte>(value));
2776}
2777
2778
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002779InstanceType Map::instance_type() {
2780 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2781}
2782
2783
2784void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002785 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2786}
2787
2788
2789int Map::unused_property_fields() {
2790 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2791}
2792
2793
2794void Map::set_unused_property_fields(int value) {
2795 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2796}
2797
2798
2799byte Map::bit_field() {
2800 return READ_BYTE_FIELD(this, kBitFieldOffset);
2801}
2802
2803
2804void Map::set_bit_field(byte value) {
2805 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2806}
2807
2808
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002809byte Map::bit_field2() {
2810 return READ_BYTE_FIELD(this, kBitField2Offset);
2811}
2812
2813
2814void Map::set_bit_field2(byte value) {
2815 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2816}
2817
2818
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002819void Map::set_non_instance_prototype(bool value) {
2820 if (value) {
2821 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2822 } else {
2823 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2824 }
2825}
2826
2827
2828bool Map::has_non_instance_prototype() {
2829 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2830}
2831
2832
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002833void Map::set_function_with_prototype(bool value) {
2834 if (value) {
2835 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2836 } else {
2837 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2838 }
2839}
2840
2841
2842bool Map::function_with_prototype() {
2843 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2844}
2845
2846
ager@chromium.org870a0b62008-11-04 11:43:05 +00002847void Map::set_is_access_check_needed(bool access_check_needed) {
2848 if (access_check_needed) {
2849 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2850 } else {
2851 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2852 }
2853}
2854
2855
2856bool Map::is_access_check_needed() {
2857 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2858}
2859
2860
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002861void Map::set_is_extensible(bool value) {
2862 if (value) {
2863 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2864 } else {
2865 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2866 }
2867}
2868
2869bool Map::is_extensible() {
2870 return ((1 << kIsExtensible) & bit_field2()) != 0;
2871}
2872
2873
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002874void Map::set_attached_to_shared_function_info(bool value) {
2875 if (value) {
2876 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2877 } else {
2878 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2879 }
2880}
2881
2882bool Map::attached_to_shared_function_info() {
2883 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2884}
2885
2886
2887void Map::set_is_shared(bool value) {
2888 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002889 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002890 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002891 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002892 }
2893}
2894
2895bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002896 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002897}
2898
2899
2900JSFunction* Map::unchecked_constructor() {
2901 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2902}
2903
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002904
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002905Code::Flags Code::flags() {
2906 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2907}
2908
2909
2910void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002911 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002912 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002913 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2914 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002915 ExtractArgumentsCountFromFlags(flags) >= 0);
2916 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2917}
2918
2919
2920Code::Kind Code::kind() {
2921 return ExtractKindFromFlags(flags());
2922}
2923
2924
kasper.lund7276f142008-07-30 08:49:36 +00002925InlineCacheState Code::ic_state() {
2926 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002927 // Only allow uninitialized or debugger states for non-IC code
2928 // objects. This is used in the debugger to determine whether or not
2929 // a call to code object has been replaced with a debug break call.
2930 ASSERT(is_inline_cache_stub() ||
2931 result == UNINITIALIZED ||
2932 result == DEBUG_BREAK ||
2933 result == DEBUG_PREPARE_STEP_IN);
2934 return result;
2935}
2936
2937
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002938Code::ExtraICState Code::extra_ic_state() {
2939 ASSERT(is_inline_cache_stub());
2940 return ExtractExtraICStateFromFlags(flags());
2941}
2942
2943
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002944PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002945 return ExtractTypeFromFlags(flags());
2946}
2947
2948
2949int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002950 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002951 return ExtractArgumentsCountFromFlags(flags());
2952}
2953
2954
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002955int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002956 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002957 kind() == UNARY_OP_IC ||
2958 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002959 kind() == COMPARE_IC ||
2960 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002961 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002962}
2963
2964
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002965void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002966 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002967 kind() == UNARY_OP_IC ||
2968 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002969 kind() == COMPARE_IC ||
2970 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002971 ASSERT(0 <= major && major < 256);
2972 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002973}
2974
2975
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002976bool Code::is_pregenerated() {
2977 return kind() == STUB && IsPregeneratedField::decode(flags());
2978}
2979
2980
2981void Code::set_is_pregenerated(bool value) {
2982 ASSERT(kind() == STUB);
2983 Flags f = flags();
2984 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
2985 set_flags(f);
2986}
2987
2988
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002989bool Code::optimizable() {
2990 ASSERT(kind() == FUNCTION);
2991 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2992}
2993
2994
2995void Code::set_optimizable(bool value) {
2996 ASSERT(kind() == FUNCTION);
2997 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2998}
2999
3000
3001bool Code::has_deoptimization_support() {
3002 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00003003 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3004 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003005}
3006
3007
3008void Code::set_has_deoptimization_support(bool value) {
3009 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00003010 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3011 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3012 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3013}
3014
3015
3016bool Code::has_debug_break_slots() {
3017 ASSERT(kind() == FUNCTION);
3018 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3019 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3020}
3021
3022
3023void Code::set_has_debug_break_slots(bool value) {
3024 ASSERT(kind() == FUNCTION);
3025 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3026 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3027 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003028}
3029
3030
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003031bool Code::is_compiled_optimizable() {
3032 ASSERT(kind() == FUNCTION);
3033 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3034 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3035}
3036
3037
3038void Code::set_compiled_optimizable(bool value) {
3039 ASSERT(kind() == FUNCTION);
3040 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3041 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3042 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3043}
3044
3045
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003046int Code::allow_osr_at_loop_nesting_level() {
3047 ASSERT(kind() == FUNCTION);
3048 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3049}
3050
3051
3052void Code::set_allow_osr_at_loop_nesting_level(int level) {
3053 ASSERT(kind() == FUNCTION);
3054 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3055 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3056}
3057
3058
3059unsigned Code::stack_slots() {
3060 ASSERT(kind() == OPTIMIZED_FUNCTION);
3061 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3062}
3063
3064
3065void Code::set_stack_slots(unsigned slots) {
3066 ASSERT(kind() == OPTIMIZED_FUNCTION);
3067 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3068}
3069
3070
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003071unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003072 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003073 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003074}
3075
3076
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003077void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003078 ASSERT(kind() == OPTIMIZED_FUNCTION);
3079 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003080 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003081}
3082
3083
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003084unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003085 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003086 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003087}
3088
3089
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003090void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003091 ASSERT(kind() == FUNCTION);
3092 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003093 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003094}
3095
3096
3097CheckType Code::check_type() {
3098 ASSERT(is_call_stub() || is_keyed_call_stub());
3099 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3100 return static_cast<CheckType>(type);
3101}
3102
3103
3104void Code::set_check_type(CheckType value) {
3105 ASSERT(is_call_stub() || is_keyed_call_stub());
3106 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3107}
3108
3109
danno@chromium.org40cb8782011-05-25 07:58:50 +00003110byte Code::unary_op_type() {
3111 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003112 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3113}
3114
3115
danno@chromium.org40cb8782011-05-25 07:58:50 +00003116void Code::set_unary_op_type(byte value) {
3117 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003118 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3119}
3120
3121
danno@chromium.org40cb8782011-05-25 07:58:50 +00003122byte Code::binary_op_type() {
3123 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003124 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3125}
3126
3127
danno@chromium.org40cb8782011-05-25 07:58:50 +00003128void Code::set_binary_op_type(byte value) {
3129 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003130 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3131}
3132
3133
danno@chromium.org40cb8782011-05-25 07:58:50 +00003134byte Code::binary_op_result_type() {
3135 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003136 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3137}
3138
3139
danno@chromium.org40cb8782011-05-25 07:58:50 +00003140void Code::set_binary_op_result_type(byte value) {
3141 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003142 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3143}
3144
3145
3146byte Code::compare_state() {
3147 ASSERT(is_compare_ic_stub());
3148 return READ_BYTE_FIELD(this, kCompareStateOffset);
3149}
3150
3151
3152void Code::set_compare_state(byte value) {
3153 ASSERT(is_compare_ic_stub());
3154 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3155}
3156
3157
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003158byte Code::to_boolean_state() {
3159 ASSERT(is_to_boolean_ic_stub());
3160 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3161}
3162
3163
3164void Code::set_to_boolean_state(byte value) {
3165 ASSERT(is_to_boolean_ic_stub());
3166 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3167}
3168
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003169
3170bool Code::has_function_cache() {
3171 ASSERT(kind() == STUB);
3172 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3173}
3174
3175
3176void Code::set_has_function_cache(bool flag) {
3177 ASSERT(kind() == STUB);
3178 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3179}
3180
3181
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003182bool Code::is_inline_cache_stub() {
3183 Kind kind = this->kind();
3184 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3185}
3186
3187
3188Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003189 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003190 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003191 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003192 int argc,
3193 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003194 // Extra IC state is only allowed for call IC stubs or for store IC
3195 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003196 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003197 kind == CALL_IC ||
3198 kind == STORE_IC ||
3199 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003200 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003201 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003202 | ICStateField::encode(ic_state)
3203 | TypeField::encode(type)
3204 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003205 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003206 | CacheHolderField::encode(holder);
3207 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003208}
3209
3210
3211Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3212 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003213 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003214 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003215 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003216 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003217}
3218
3219
3220Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003221 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003222}
3223
3224
kasper.lund7276f142008-07-30 08:49:36 +00003225InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003226 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003227}
3228
3229
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003230Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003231 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003232}
3233
3234
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003235PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003236 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003237}
3238
3239
3240int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003241 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003242}
3243
3244
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003245InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003246 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003247}
3248
3249
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003250Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003251 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003252 return static_cast<Flags>(bits);
3253}
3254
3255
ager@chromium.org8bb60582008-12-11 12:02:20 +00003256Code* Code::GetCodeFromTargetAddress(Address address) {
3257 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3258 // GetCodeFromTargetAddress might be called when marking objects during mark
3259 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3260 // Code::cast. Code::cast does not work when the object's map is
3261 // marked.
3262 Code* result = reinterpret_cast<Code*>(code);
3263 return result;
3264}
3265
3266
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003267Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3268 return HeapObject::
3269 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3270}
3271
3272
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003273Object* Map::prototype() {
3274 return READ_FIELD(this, kPrototypeOffset);
3275}
3276
3277
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003278void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003279 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003280 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003281 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003282}
3283
3284
danno@chromium.org40cb8782011-05-25 07:58:50 +00003285DescriptorArray* Map::instance_descriptors() {
3286 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3287 if (object->IsSmi()) {
3288 return HEAP->empty_descriptor_array();
3289 } else {
3290 return DescriptorArray::cast(object);
3291 }
3292}
3293
3294
3295void Map::init_instance_descriptors() {
3296 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3297}
3298
3299
3300void Map::clear_instance_descriptors() {
3301 Object* object = READ_FIELD(this,
3302 kInstanceDescriptorsOrBitField3Offset);
3303 if (!object->IsSmi()) {
3304 WRITE_FIELD(
3305 this,
3306 kInstanceDescriptorsOrBitField3Offset,
3307 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3308 }
3309}
3310
3311
3312void Map::set_instance_descriptors(DescriptorArray* value,
3313 WriteBarrierMode mode) {
3314 Object* object = READ_FIELD(this,
3315 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003316 Heap* heap = GetHeap();
3317 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003318 clear_instance_descriptors();
3319 return;
3320 } else {
3321 if (object->IsSmi()) {
3322 value->set_bit_field3_storage(Smi::cast(object)->value());
3323 } else {
3324 value->set_bit_field3_storage(
3325 DescriptorArray::cast(object)->bit_field3_storage());
3326 }
3327 }
3328 ASSERT(!is_shared());
3329 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003330 CONDITIONAL_WRITE_BARRIER(
3331 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003332}
3333
3334
3335int Map::bit_field3() {
3336 Object* object = READ_FIELD(this,
3337 kInstanceDescriptorsOrBitField3Offset);
3338 if (object->IsSmi()) {
3339 return Smi::cast(object)->value();
3340 } else {
3341 return DescriptorArray::cast(object)->bit_field3_storage();
3342 }
3343}
3344
3345
3346void Map::set_bit_field3(int value) {
3347 ASSERT(Smi::IsValid(value));
3348 Object* object = READ_FIELD(this,
3349 kInstanceDescriptorsOrBitField3Offset);
3350 if (object->IsSmi()) {
3351 WRITE_FIELD(this,
3352 kInstanceDescriptorsOrBitField3Offset,
3353 Smi::FromInt(value));
3354 } else {
3355 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3356 }
3357}
3358
3359
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003360FixedArray* Map::unchecked_prototype_transitions() {
3361 return reinterpret_cast<FixedArray*>(
3362 READ_FIELD(this, kPrototypeTransitionsOffset));
3363}
3364
3365
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003366ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003367ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003368ACCESSORS(Map, constructor, Object, kConstructorOffset)
3369
3370ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003371ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003372ACCESSORS(JSFunction,
3373 next_function_link,
3374 Object,
3375 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003376
3377ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3378ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003379ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003380
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003381ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003382
3383ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3384ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3385ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3386ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3387ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3388
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003389ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3390ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3391
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003392ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3393ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3394ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3395
3396ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3397ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3398ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3399ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3400ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3401ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3402
3403ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3404ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3405
3406ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3407ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3408
3409ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3410ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003411ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3412 kPropertyAccessorsOffset)
3413ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3414 kPrototypeTemplateOffset)
3415ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3416ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3417 kNamedPropertyHandlerOffset)
3418ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3419 kIndexedPropertyHandlerOffset)
3420ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3421 kInstanceTemplateOffset)
3422ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3423ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003424ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3425 kInstanceCallHandlerOffset)
3426ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3427 kAccessCheckInfoOffset)
3428ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3429
3430ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003431ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3432 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003433
3434ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3435ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3436
3437ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3438
3439ACCESSORS(Script, source, Object, kSourceOffset)
3440ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003441ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003442ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3443ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003444ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003445ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003446ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003447ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003448ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003449ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003450ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003451ACCESSORS(Script, eval_from_instructions_offset, Smi,
3452 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003453
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003454#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003455ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3456ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3457ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3458ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3459
3460ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3461ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3462ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3463ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003464#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003465
3466ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003467ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3468ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003469ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3470 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003471ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003472ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3473ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003474ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003475ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3476 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003477
3478BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3479 kHiddenPrototypeBit)
3480BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3481BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3482 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003483BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3484 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003485BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3486 kIsExpressionBit)
3487BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3488 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003489BOOL_GETTER(SharedFunctionInfo,
3490 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003491 has_only_simple_this_property_assignments,
3492 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003493BOOL_ACCESSORS(SharedFunctionInfo,
3494 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003495 allows_lazy_compilation,
3496 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003497BOOL_ACCESSORS(SharedFunctionInfo,
3498 compiler_hints,
3499 uses_arguments,
3500 kUsesArguments)
3501BOOL_ACCESSORS(SharedFunctionInfo,
3502 compiler_hints,
3503 has_duplicate_parameters,
3504 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003505
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003506
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003507#if V8_HOST_ARCH_32_BIT
3508SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3509SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003510 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003511SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003512 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003513SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3514SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003515 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003516SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3517SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003518 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003519SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003520 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003521SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003522 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003523SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003524#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003525
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003526#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003527 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003528 int holder::name() { \
3529 int value = READ_INT_FIELD(this, offset); \
3530 ASSERT(kHeapObjectTag == 1); \
3531 ASSERT((value & kHeapObjectTag) == 0); \
3532 return value >> 1; \
3533 } \
3534 void holder::set_##name(int value) { \
3535 ASSERT(kHeapObjectTag == 1); \
3536 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3537 (value & 0xC0000000) == 0x000000000); \
3538 WRITE_INT_FIELD(this, \
3539 offset, \
3540 (value << 1) & ~kHeapObjectTag); \
3541 }
3542
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003543#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3544 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003545 INT_ACCESSORS(holder, name, offset)
3546
3547
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003548PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003549PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3550 formal_parameter_count,
3551 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003552
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003553PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3554 expected_nof_properties,
3555 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003556PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3557
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003558PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3559PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3560 start_position_and_type,
3561 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003562
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003563PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3564 function_token_position,
3565 kFunctionTokenPositionOffset)
3566PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3567 compiler_hints,
3568 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003569
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003570PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3571 this_property_assignments_count,
3572 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003573PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003574#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003575
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003576
3577int SharedFunctionInfo::construction_count() {
3578 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3579}
3580
3581
3582void SharedFunctionInfo::set_construction_count(int value) {
3583 ASSERT(0 <= value && value < 256);
3584 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3585}
3586
3587
whesse@chromium.org7b260152011-06-20 15:33:18 +00003588BOOL_ACCESSORS(SharedFunctionInfo,
3589 compiler_hints,
3590 live_objects_may_exist,
3591 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003592
3593
3594bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003595 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003596}
3597
3598
whesse@chromium.org7b260152011-06-20 15:33:18 +00003599BOOL_GETTER(SharedFunctionInfo,
3600 compiler_hints,
3601 optimization_disabled,
3602 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003603
3604
3605void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3606 set_compiler_hints(BooleanBit::set(compiler_hints(),
3607 kOptimizationDisabled,
3608 disable));
3609 // If disabling optimizations we reflect that in the code object so
3610 // it will not be counted as optimizable code.
3611 if ((code()->kind() == Code::FUNCTION) && disable) {
3612 code()->set_optimizable(false);
3613 }
3614}
3615
3616
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003617LanguageMode SharedFunctionInfo::language_mode() {
3618 int hints = compiler_hints();
3619 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3620 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3621 return EXTENDED_MODE;
3622 }
3623 return BooleanBit::get(hints, kStrictModeFunction)
3624 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003625}
3626
3627
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003628void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3629 // We only allow language mode transitions that go set the same language mode
3630 // again or go up in the chain:
3631 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3632 ASSERT(this->language_mode() == CLASSIC_MODE ||
3633 this->language_mode() == language_mode ||
3634 language_mode == EXTENDED_MODE);
3635 int hints = compiler_hints();
3636 hints = BooleanBit::set(
3637 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3638 hints = BooleanBit::set(
3639 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3640 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003641}
3642
3643
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003644bool SharedFunctionInfo::is_classic_mode() {
3645 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3646}
3647
3648BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3649 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003650BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3651BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3652 name_should_print_as_anonymous,
3653 kNameShouldPrintAsAnonymous)
3654BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3655BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003656
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003657ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3658ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3659
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003660ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3661
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003662bool Script::HasValidSource() {
3663 Object* src = this->source();
3664 if (!src->IsString()) return true;
3665 String* src_str = String::cast(src);
3666 if (!StringShape(src_str).IsExternal()) return true;
3667 if (src_str->IsAsciiRepresentation()) {
3668 return ExternalAsciiString::cast(src)->resource() != NULL;
3669 } else if (src_str->IsTwoByteRepresentation()) {
3670 return ExternalTwoByteString::cast(src)->resource() != NULL;
3671 }
3672 return true;
3673}
3674
3675
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003676void SharedFunctionInfo::DontAdaptArguments() {
3677 ASSERT(code()->kind() == Code::BUILTIN);
3678 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3679}
3680
3681
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003682int SharedFunctionInfo::start_position() {
3683 return start_position_and_type() >> kStartPositionShift;
3684}
3685
3686
3687void SharedFunctionInfo::set_start_position(int start_position) {
3688 set_start_position_and_type((start_position << kStartPositionShift)
3689 | (start_position_and_type() & ~kStartPositionMask));
3690}
3691
3692
3693Code* SharedFunctionInfo::code() {
3694 return Code::cast(READ_FIELD(this, kCodeOffset));
3695}
3696
3697
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003698Code* SharedFunctionInfo::unchecked_code() {
3699 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3700}
3701
3702
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003703void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003704 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003705 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003706}
3707
3708
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003709ScopeInfo* SharedFunctionInfo::scope_info() {
3710 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003711}
3712
3713
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003714void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003715 WriteBarrierMode mode) {
3716 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003717 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3718 this,
3719 kScopeInfoOffset,
3720 reinterpret_cast<Object*>(value),
3721 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003722}
3723
3724
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003725Smi* SharedFunctionInfo::deopt_counter() {
3726 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3727}
3728
3729
3730void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3731 WRITE_FIELD(this, kDeoptCounterOffset, value);
3732}
3733
3734
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003735bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003736 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003737 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003738}
3739
3740
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003741bool SharedFunctionInfo::IsApiFunction() {
3742 return function_data()->IsFunctionTemplateInfo();
3743}
3744
3745
3746FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3747 ASSERT(IsApiFunction());
3748 return FunctionTemplateInfo::cast(function_data());
3749}
3750
3751
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003752bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003753 return function_data()->IsSmi();
3754}
3755
3756
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003757BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3758 ASSERT(HasBuiltinFunctionId());
3759 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003760}
3761
3762
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003763int SharedFunctionInfo::code_age() {
3764 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3765}
3766
3767
3768void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00003769 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3770 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003771}
3772
3773
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003774bool SharedFunctionInfo::has_deoptimization_support() {
3775 Code* code = this->code();
3776 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3777}
3778
3779
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003780bool JSFunction::IsBuiltin() {
3781 return context()->global()->IsJSBuiltinsObject();
3782}
3783
3784
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003785bool JSFunction::NeedsArgumentsAdaption() {
3786 return shared()->formal_parameter_count() !=
3787 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3788}
3789
3790
3791bool JSFunction::IsOptimized() {
3792 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3793}
3794
3795
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003796bool JSFunction::IsOptimizable() {
3797 return code()->kind() == Code::FUNCTION && code()->optimizable();
3798}
3799
3800
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003801bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003802 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003803}
3804
3805
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003806Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003807 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003808}
3809
3810
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003811Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003812 return reinterpret_cast<Code*>(
3813 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003814}
3815
3816
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003817void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003818 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003819 Address entry = value->entry();
3820 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003821 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3822 this,
3823 HeapObject::RawField(this, kCodeEntryOffset),
3824 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003825}
3826
3827
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003828void JSFunction::ReplaceCode(Code* code) {
3829 bool was_optimized = IsOptimized();
3830 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3831
3832 set_code(code);
3833
3834 // Add/remove the function from the list of optimized functions for this
3835 // context based on the state change.
3836 if (!was_optimized && is_optimized) {
3837 context()->global_context()->AddOptimizedFunction(this);
3838 }
3839 if (was_optimized && !is_optimized) {
3840 context()->global_context()->RemoveOptimizedFunction(this);
3841 }
3842}
3843
3844
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003845Context* JSFunction::context() {
3846 return Context::cast(READ_FIELD(this, kContextOffset));
3847}
3848
3849
3850Object* JSFunction::unchecked_context() {
3851 return READ_FIELD(this, kContextOffset);
3852}
3853
3854
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003855SharedFunctionInfo* JSFunction::unchecked_shared() {
3856 return reinterpret_cast<SharedFunctionInfo*>(
3857 READ_FIELD(this, kSharedFunctionInfoOffset));
3858}
3859
3860
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003861void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003862 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003863 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003864 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003865}
3866
3867ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3868 kPrototypeOrInitialMapOffset)
3869
3870
3871Map* JSFunction::initial_map() {
3872 return Map::cast(prototype_or_initial_map());
3873}
3874
3875
3876void JSFunction::set_initial_map(Map* value) {
3877 set_prototype_or_initial_map(value);
3878}
3879
3880
3881bool JSFunction::has_initial_map() {
3882 return prototype_or_initial_map()->IsMap();
3883}
3884
3885
3886bool JSFunction::has_instance_prototype() {
3887 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3888}
3889
3890
3891bool JSFunction::has_prototype() {
3892 return map()->has_non_instance_prototype() || has_instance_prototype();
3893}
3894
3895
3896Object* JSFunction::instance_prototype() {
3897 ASSERT(has_instance_prototype());
3898 if (has_initial_map()) return initial_map()->prototype();
3899 // When there is no initial map and the prototype is a JSObject, the
3900 // initial map field is used for the prototype field.
3901 return prototype_or_initial_map();
3902}
3903
3904
3905Object* JSFunction::prototype() {
3906 ASSERT(has_prototype());
3907 // If the function's prototype property has been set to a non-JSObject
3908 // value, that value is stored in the constructor field of the map.
3909 if (map()->has_non_instance_prototype()) return map()->constructor();
3910 return instance_prototype();
3911}
3912
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003913bool JSFunction::should_have_prototype() {
3914 return map()->function_with_prototype();
3915}
3916
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003917
3918bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003919 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003920}
3921
3922
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003923FixedArray* JSFunction::literals() {
3924 ASSERT(!shared()->bound());
3925 return literals_or_bindings();
3926}
3927
3928
3929void JSFunction::set_literals(FixedArray* literals) {
3930 ASSERT(!shared()->bound());
3931 set_literals_or_bindings(literals);
3932}
3933
3934
3935FixedArray* JSFunction::function_bindings() {
3936 ASSERT(shared()->bound());
3937 return literals_or_bindings();
3938}
3939
3940
3941void JSFunction::set_function_bindings(FixedArray* bindings) {
3942 ASSERT(shared()->bound());
3943 // Bound function literal may be initialized to the empty fixed array
3944 // before the bindings are set.
3945 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
3946 bindings->map() == GetHeap()->fixed_cow_array_map());
3947 set_literals_or_bindings(bindings);
3948}
3949
3950
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003951int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003952 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003953 return literals()->length();
3954}
3955
3956
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003957Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003958 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003959 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003960}
3961
3962
3963void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3964 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003965 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003966 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003967 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003968}
3969
3970
3971Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003972 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003973 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3974}
3975
3976
3977void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3978 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003979 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003980 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003981 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003982}
3983
3984
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003985ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003986ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003987ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
3988ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
3989
3990
3991void JSProxy::InitializeBody(int object_size, Object* value) {
3992 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
3993 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
3994 WRITE_FIELD(this, offset, value);
3995 }
3996}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003997
3998
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003999ACCESSORS(JSSet, table, Object, kTableOffset)
4000ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004001ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4002ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004003
4004
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004005Address Foreign::foreign_address() {
4006 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004007}
4008
4009
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004010void Foreign::set_foreign_address(Address value) {
4011 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004012}
4013
4014
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004015ACCESSORS(JSValue, value, Object, kValueOffset)
4016
4017
4018JSValue* JSValue::cast(Object* obj) {
4019 ASSERT(obj->IsJSValue());
4020 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4021 return reinterpret_cast<JSValue*>(obj);
4022}
4023
4024
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004025ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4026ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4027ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4028ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4029ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4030SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4031SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4032
4033
4034JSMessageObject* JSMessageObject::cast(Object* obj) {
4035 ASSERT(obj->IsJSMessageObject());
4036 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4037 return reinterpret_cast<JSMessageObject*>(obj);
4038}
4039
4040
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004041INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004042ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004043ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004044ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004045ACCESSORS(Code, next_code_flushing_candidate,
4046 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004047
4048
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004049byte* Code::instruction_start() {
4050 return FIELD_ADDR(this, kHeaderSize);
4051}
4052
4053
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004054byte* Code::instruction_end() {
4055 return instruction_start() + instruction_size();
4056}
4057
4058
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004059int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004060 return RoundUp(instruction_size(), kObjectAlignment);
4061}
4062
4063
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004064FixedArray* Code::unchecked_deoptimization_data() {
4065 return reinterpret_cast<FixedArray*>(
4066 READ_FIELD(this, kDeoptimizationDataOffset));
4067}
4068
4069
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004070ByteArray* Code::unchecked_relocation_info() {
4071 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004072}
4073
4074
4075byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004076 return unchecked_relocation_info()->GetDataStartAddress();
4077}
4078
4079
4080int Code::relocation_size() {
4081 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004082}
4083
4084
4085byte* Code::entry() {
4086 return instruction_start();
4087}
4088
4089
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004090bool Code::contains(byte* inner_pointer) {
4091 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004092}
4093
4094
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004095ACCESSORS(JSArray, length, Object, kLengthOffset)
4096
4097
ager@chromium.org236ad962008-09-25 09:45:57 +00004098ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004099
4100
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004101JSRegExp::Type JSRegExp::TypeTag() {
4102 Object* data = this->data();
4103 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4104 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4105 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004106}
4107
4108
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004109JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4110 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4111 return static_cast<JSRegExp::Type>(smi->value());
4112}
4113
4114
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004115int JSRegExp::CaptureCount() {
4116 switch (TypeTag()) {
4117 case ATOM:
4118 return 0;
4119 case IRREGEXP:
4120 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4121 default:
4122 UNREACHABLE();
4123 return -1;
4124 }
4125}
4126
4127
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004128JSRegExp::Flags JSRegExp::GetFlags() {
4129 ASSERT(this->data()->IsFixedArray());
4130 Object* data = this->data();
4131 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4132 return Flags(smi->value());
4133}
4134
4135
4136String* JSRegExp::Pattern() {
4137 ASSERT(this->data()->IsFixedArray());
4138 Object* data = this->data();
4139 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4140 return pattern;
4141}
4142
4143
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004144Object* JSRegExp::DataAt(int index) {
4145 ASSERT(TypeTag() != NOT_COMPILED);
4146 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004147}
4148
4149
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004150Object* JSRegExp::DataAtUnchecked(int index) {
4151 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4152 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4153 return READ_FIELD(fa, offset);
4154}
4155
4156
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004157void JSRegExp::SetDataAt(int index, Object* value) {
4158 ASSERT(TypeTag() != NOT_COMPILED);
4159 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4160 FixedArray::cast(data())->set(index, value);
4161}
4162
4163
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004164void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4165 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4166 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4167 if (value->IsSmi()) {
4168 fa->set_unchecked(index, Smi::cast(value));
4169 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004170 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004171 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4172 }
4173}
4174
4175
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004176ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004177 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004178#if DEBUG
4179 FixedArrayBase* fixed_array =
4180 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4181 Map* map = fixed_array->map();
4182 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004183 (map == GetHeap()->fixed_array_map() ||
4184 map == GetHeap()->fixed_cow_array_map())) ||
4185 (kind == FAST_DOUBLE_ELEMENTS &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004186 (fixed_array->IsFixedDoubleArray() ||
4187 fixed_array == GetHeap()->empty_fixed_array())) ||
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004188 (kind == DICTIONARY_ELEMENTS &&
4189 fixed_array->IsFixedArray() &&
4190 fixed_array->IsDictionary()) ||
4191 (kind > DICTIONARY_ELEMENTS));
4192 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4193 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004194#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004195 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004196}
4197
4198
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004199ElementsAccessor* JSObject::GetElementsAccessor() {
4200 return ElementsAccessor::ForKind(GetElementsKind());
4201}
4202
4203
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004204bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004205 return GetElementsKind() == FAST_ELEMENTS;
4206}
4207
4208
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004209bool JSObject::HasFastSmiOnlyElements() {
4210 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4211}
4212
4213
4214bool JSObject::HasFastTypeElements() {
4215 ElementsKind elements_kind = GetElementsKind();
4216 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4217 elements_kind == FAST_ELEMENTS;
4218}
4219
4220
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004221bool JSObject::HasFastDoubleElements() {
4222 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4223}
4224
4225
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004226bool JSObject::HasDictionaryElements() {
4227 return GetElementsKind() == DICTIONARY_ELEMENTS;
4228}
4229
4230
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004231bool JSObject::HasNonStrictArgumentsElements() {
4232 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4233}
4234
4235
ager@chromium.org3811b432009-10-28 14:53:37 +00004236bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004237 HeapObject* array = elements();
4238 ASSERT(array != NULL);
4239 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004240}
4241
4242
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004243#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4244bool JSObject::HasExternal##name##Elements() { \
4245 HeapObject* array = elements(); \
4246 ASSERT(array != NULL); \
4247 if (!array->IsHeapObject()) \
4248 return false; \
4249 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004250}
4251
4252
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004253EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4254EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4255EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4256EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4257 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4258EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4259EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4260 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4261EXTERNAL_ELEMENTS_CHECK(Float,
4262 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004263EXTERNAL_ELEMENTS_CHECK(Double,
4264 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004265EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004266
4267
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004268bool JSObject::HasNamedInterceptor() {
4269 return map()->has_named_interceptor();
4270}
4271
4272
4273bool JSObject::HasIndexedInterceptor() {
4274 return map()->has_indexed_interceptor();
4275}
4276
4277
lrn@chromium.org303ada72010-10-27 09:33:13 +00004278MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004279 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004280 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004281 Isolate* isolate = GetIsolate();
4282 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004283 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004284 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4285 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004286 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4287 return maybe_writable_elems;
4288 }
4289 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004290 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004291 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004292 return writable_elems;
4293}
4294
4295
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004296StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004297 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004298 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004299}
4300
4301
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004302SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004303 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004304 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004305}
4306
4307
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004308bool String::IsHashFieldComputed(uint32_t field) {
4309 return (field & kHashNotComputedMask) == 0;
4310}
4311
4312
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004313bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004314 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004315}
4316
4317
4318uint32_t String::Hash() {
4319 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004320 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004321 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004322 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004323 return ComputeAndSetHash();
4324}
4325
4326
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004327StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004328 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004329 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004330 array_index_(0),
4331 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4332 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004333 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004334 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004335}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004336
4337
4338bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004339 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004340}
4341
4342
4343void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004344 // Use the Jenkins one-at-a-time hash function to update the hash
4345 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004346 raw_running_hash_ += c;
4347 raw_running_hash_ += (raw_running_hash_ << 10);
4348 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004349 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004350 if (is_array_index_) {
4351 if (c < '0' || c > '9') {
4352 is_array_index_ = false;
4353 } else {
4354 int d = c - '0';
4355 if (is_first_char_) {
4356 is_first_char_ = false;
4357 if (c == '0' && length_ > 1) {
4358 is_array_index_ = false;
4359 return;
4360 }
4361 }
4362 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4363 is_array_index_ = false;
4364 } else {
4365 array_index_ = array_index_ * 10 + d;
4366 }
4367 }
4368 }
4369}
4370
4371
4372void StringHasher::AddCharacterNoIndex(uc32 c) {
4373 ASSERT(!is_array_index());
4374 raw_running_hash_ += c;
4375 raw_running_hash_ += (raw_running_hash_ << 10);
4376 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4377}
4378
4379
4380uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004381 // Get the calculated raw hash value and do some more bit ops to distribute
4382 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004383 uint32_t result = raw_running_hash_;
4384 result += (result << 3);
4385 result ^= (result >> 11);
4386 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004387 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004388 result = 27;
4389 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004390 return result;
4391}
4392
4393
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004394template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004395uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4396 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004397 if (!hasher.has_trivial_hash()) {
4398 int i;
4399 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4400 hasher.AddCharacter(chars[i]);
4401 }
4402 for (; i < length; i++) {
4403 hasher.AddCharacterNoIndex(chars[i]);
4404 }
4405 }
4406 return hasher.GetHashField();
4407}
4408
4409
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004410bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004411 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004412 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4413 return false;
4414 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004415 return SlowAsArrayIndex(index);
4416}
4417
4418
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004419Object* JSReceiver::GetPrototype() {
4420 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004421}
4422
4423
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004424bool JSReceiver::HasProperty(String* name) {
4425 if (IsJSProxy()) {
4426 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4427 }
4428 return GetPropertyAttribute(name) != ABSENT;
4429}
4430
4431
4432bool JSReceiver::HasLocalProperty(String* name) {
4433 if (IsJSProxy()) {
4434 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4435 }
4436 return GetLocalPropertyAttribute(name) != ABSENT;
4437}
4438
4439
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004440PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004441 return GetPropertyAttributeWithReceiver(this, key);
4442}
4443
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004444// TODO(504): this may be useful in other places too where JSGlobalProxy
4445// is used.
4446Object* JSObject::BypassGlobalProxy() {
4447 if (IsJSGlobalProxy()) {
4448 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004449 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004450 ASSERT(proto->IsJSGlobalObject());
4451 return proto;
4452 }
4453 return this;
4454}
4455
4456
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004457MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4458 return IsJSProxy()
4459 ? JSProxy::cast(this)->GetIdentityHash(flag)
4460 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004461}
4462
4463
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004464bool JSReceiver::HasElement(uint32_t index) {
4465 if (IsJSProxy()) {
4466 return JSProxy::cast(this)->HasElementWithHandler(index);
4467 }
4468 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004469}
4470
4471
4472bool AccessorInfo::all_can_read() {
4473 return BooleanBit::get(flag(), kAllCanReadBit);
4474}
4475
4476
4477void AccessorInfo::set_all_can_read(bool value) {
4478 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4479}
4480
4481
4482bool AccessorInfo::all_can_write() {
4483 return BooleanBit::get(flag(), kAllCanWriteBit);
4484}
4485
4486
4487void AccessorInfo::set_all_can_write(bool value) {
4488 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4489}
4490
4491
ager@chromium.org870a0b62008-11-04 11:43:05 +00004492bool AccessorInfo::prohibits_overwriting() {
4493 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4494}
4495
4496
4497void AccessorInfo::set_prohibits_overwriting(bool value) {
4498 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4499}
4500
4501
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004502PropertyAttributes AccessorInfo::property_attributes() {
4503 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4504}
4505
4506
4507void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004508 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004509}
4510
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004511
4512template<typename Shape, typename Key>
4513void Dictionary<Shape, Key>::SetEntry(int entry,
4514 Object* key,
4515 Object* value) {
4516 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4517}
4518
4519
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004520template<typename Shape, typename Key>
4521void Dictionary<Shape, Key>::SetEntry(int entry,
4522 Object* key,
4523 Object* value,
4524 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004525 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004526 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004527 AssertNoAllocation no_gc;
4528 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004529 FixedArray::set(index, key, mode);
4530 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004531 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004532}
4533
4534
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004535bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4536 ASSERT(other->IsNumber());
4537 return key == static_cast<uint32_t>(other->Number());
4538}
4539
4540
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004541uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
4542 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004543}
4544
4545
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004546uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
4547 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004548 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004549 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004550}
4551
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004552uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
4553 return ComputeIntegerHash(key, seed);
4554}
4555
4556uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
4557 uint32_t seed,
4558 Object* other) {
4559 ASSERT(other->IsNumber());
4560 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
4561}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004562
4563MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4564 return Isolate::Current()->heap()->NumberFromUint32(key);
4565}
4566
4567
4568bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4569 // We know that all entries in a hash table had their hash keys created.
4570 // Use that knowledge to have fast failure.
4571 if (key->Hash() != String::cast(other)->Hash()) return false;
4572 return key->Equals(String::cast(other));
4573}
4574
4575
4576uint32_t StringDictionaryShape::Hash(String* key) {
4577 return key->Hash();
4578}
4579
4580
4581uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4582 return String::cast(other)->Hash();
4583}
4584
4585
4586MaybeObject* StringDictionaryShape::AsObject(String* key) {
4587 return key;
4588}
4589
4590
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004591template <int entrysize>
4592bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4593 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004594}
4595
4596
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004597template <int entrysize>
4598uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004599 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4600 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004601}
4602
4603
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004604template <int entrysize>
4605uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4606 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004607 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4608 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004609}
4610
4611
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004612template <int entrysize>
4613MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004614 return key;
4615}
4616
4617
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004618void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004619 // No write barrier is needed since empty_fixed_array is not in new space.
4620 // Please note this function is used during marking:
4621 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004622 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4623 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004624}
4625
4626
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004627void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004628 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004629 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004630 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4631 if (elts->length() < required_size) {
4632 // Doubling in size would be overkill, but leave some slack to avoid
4633 // constantly growing.
4634 Expand(required_size + (required_size >> 3));
4635 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004636 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004637 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4638 // Expand will allocate a new backing store in new space even if the size
4639 // we asked for isn't larger than what we had before.
4640 Expand(required_size);
4641 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004642}
4643
4644
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004645void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004646 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004647 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4648}
4649
4650
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004651bool JSArray::AllowsSetElementsLength() {
4652 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4653 ASSERT(result == !HasExternalArrayElements());
4654 return result;
4655}
4656
4657
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004658MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4659 MaybeObject* maybe_result = EnsureCanContainElements(
4660 storage, ALLOW_COPIED_DOUBLE_ELEMENTS);
4661 if (maybe_result->IsFailure()) return maybe_result;
4662 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4663 GetElementsKind() == FAST_DOUBLE_ELEMENTS) ||
4664 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4665 ((GetElementsKind() == FAST_ELEMENTS) ||
4666 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS &&
4667 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004668 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004669 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004670 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004671}
4672
4673
lrn@chromium.org303ada72010-10-27 09:33:13 +00004674MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004675 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004676 return GetHeap()->CopyFixedArray(this);
4677}
4678
4679
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004680MaybeObject* FixedDoubleArray::Copy() {
4681 if (length() == 0) return this;
4682 return GetHeap()->CopyFixedDoubleArray(this);
4683}
4684
4685
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004686Relocatable::Relocatable(Isolate* isolate) {
4687 ASSERT(isolate == Isolate::Current());
4688 isolate_ = isolate;
4689 prev_ = isolate->relocatable_top();
4690 isolate->set_relocatable_top(this);
4691}
4692
4693
4694Relocatable::~Relocatable() {
4695 ASSERT(isolate_ == Isolate::Current());
4696 ASSERT_EQ(isolate_->relocatable_top(), this);
4697 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004698}
4699
4700
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004701int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4702 return map->instance_size();
4703}
4704
4705
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004706void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004707 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004708 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004709}
4710
4711
4712template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004713void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004714 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004715 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004716}
4717
4718
4719void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4720 typedef v8::String::ExternalAsciiStringResource Resource;
4721 v->VisitExternalAsciiString(
4722 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4723}
4724
4725
4726template<typename StaticVisitor>
4727void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4728 typedef v8::String::ExternalAsciiStringResource Resource;
4729 StaticVisitor::VisitExternalAsciiString(
4730 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4731}
4732
4733
4734void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4735 typedef v8::String::ExternalStringResource Resource;
4736 v->VisitExternalTwoByteString(
4737 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4738}
4739
4740
4741template<typename StaticVisitor>
4742void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4743 typedef v8::String::ExternalStringResource Resource;
4744 StaticVisitor::VisitExternalTwoByteString(
4745 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4746}
4747
4748#define SLOT_ADDR(obj, offset) \
4749 reinterpret_cast<Object**>((obj)->address() + offset)
4750
4751template<int start_offset, int end_offset, int size>
4752void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4753 HeapObject* obj,
4754 ObjectVisitor* v) {
4755 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4756}
4757
4758
4759template<int start_offset>
4760void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4761 int object_size,
4762 ObjectVisitor* v) {
4763 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4764}
4765
4766#undef SLOT_ADDR
4767
4768
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004769#undef CAST_ACCESSOR
4770#undef INT_ACCESSORS
4771#undef SMI_ACCESSORS
4772#undef ACCESSORS
4773#undef FIELD_ADDR
4774#undef READ_FIELD
4775#undef WRITE_FIELD
4776#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004777#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004778#undef READ_MEMADDR_FIELD
4779#undef WRITE_MEMADDR_FIELD
4780#undef READ_DOUBLE_FIELD
4781#undef WRITE_DOUBLE_FIELD
4782#undef READ_INT_FIELD
4783#undef WRITE_INT_FIELD
4784#undef READ_SHORT_FIELD
4785#undef WRITE_SHORT_FIELD
4786#undef READ_BYTE_FIELD
4787#undef WRITE_BYTE_FIELD
4788
4789
4790} } // namespace v8::internal
4791
4792#endif // V8_OBJECTS_INL_H_