blob: 677d567b7a323441078714b02ebc87c18864b404 [file] [log] [blame]
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001// Copyright 2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27//
28// Review notes:
29//
ager@chromium.org32912102009-01-16 10:38:43 +000030// - The use of macros in these inline functions may seem superfluous
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000031// but it is absolutely needed to make sure gcc generates optimal
32// code. gcc is not happy when attempting to inline too deep.
33//
34
35#ifndef V8_OBJECTS_INL_H_
36#define V8_OBJECTS_INL_H_
37
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +000038#include "elements.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000039#include "objects.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000040#include "contexts.h"
41#include "conversions-inl.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000042#include "heap.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000043#include "isolate.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000044#include "property.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000045#include "spaces.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000046#include "store-buffer.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000047#include "v8memory.h"
danno@chromium.orgfa458e42012-02-01 10:48:36 +000048#include "factory.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000049#include "incremental-marking.h"
50
kasperl@chromium.org71affb52009-05-26 05:44:31 +000051namespace v8 {
52namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000053
54PropertyDetails::PropertyDetails(Smi* smi) {
55 value_ = smi->value();
56}
57
58
59Smi* PropertyDetails::AsSmi() {
60 return Smi::FromInt(value_);
61}
62
63
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000064PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000065 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000066 return PropertyDetails(smi);
67}
68
69
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000070#define TYPE_CHECKER(type, instancetype) \
71 bool Object::Is##type() { \
72 return Object::IsHeapObject() && \
73 HeapObject::cast(this)->map()->instance_type() == instancetype; \
74 }
75
76
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000077#define CAST_ACCESSOR(type) \
78 type* type::cast(Object* object) { \
79 ASSERT(object->Is##type()); \
80 return reinterpret_cast<type*>(object); \
81 }
82
83
84#define INT_ACCESSORS(holder, name, offset) \
85 int holder::name() { return READ_INT_FIELD(this, offset); } \
86 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
87
88
89#define ACCESSORS(holder, name, type, offset) \
90 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000091 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000092 WRITE_FIELD(this, offset, value); \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000093 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000094 }
95
96
rossberg@chromium.org2c067b12012-03-19 11:01:52 +000097// Getter that returns a tagged Smi and setter that writes a tagged Smi.
98#define ACCESSORS_TO_SMI(holder, name, offset) \
99 Smi* holder::name() { return Smi::cast(READ_FIELD(this, offset)); } \
100 void holder::set_##name(Smi* value, WriteBarrierMode mode) { \
101 WRITE_FIELD(this, offset, value); \
102 }
103
104
105// Getter that returns a Smi as an int and writes an int as a Smi.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000106#define SMI_ACCESSORS(holder, name, offset) \
107 int holder::name() { \
108 Object* value = READ_FIELD(this, offset); \
109 return Smi::cast(value)->value(); \
110 } \
111 void holder::set_##name(int value) { \
112 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
113 }
114
115
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000116#define BOOL_GETTER(holder, field, name, offset) \
117 bool holder::name() { \
118 return BooleanBit::get(field(), offset); \
119 } \
120
121
122#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000123 bool holder::name() { \
124 return BooleanBit::get(field(), offset); \
125 } \
126 void holder::set_##name(bool value) { \
127 set_##field(BooleanBit::set(field(), offset, value)); \
128 }
129
130
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000131bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
132 ElementsKind to_kind) {
133 if (to_kind == FAST_ELEMENTS) {
134 return from_kind == FAST_SMI_ONLY_ELEMENTS ||
135 from_kind == FAST_DOUBLE_ELEMENTS;
136 } else {
137 return to_kind == FAST_DOUBLE_ELEMENTS &&
138 from_kind == FAST_SMI_ONLY_ELEMENTS;
139 }
140}
141
142
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000143bool Object::IsFixedArrayBase() {
144 return IsFixedArray() || IsFixedDoubleArray();
145}
146
147
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000148bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
149 // There is a constraint on the object; check.
150 if (!this->IsJSObject()) return false;
151 // Fetch the constructor function of the object.
152 Object* cons_obj = JSObject::cast(this)->map()->constructor();
153 if (!cons_obj->IsJSFunction()) return false;
154 JSFunction* fun = JSFunction::cast(cons_obj);
155 // Iterate through the chain of inheriting function templates to
156 // see if the required one occurs.
157 for (Object* type = fun->shared()->function_data();
158 type->IsFunctionTemplateInfo();
159 type = FunctionTemplateInfo::cast(type)->parent_template()) {
160 if (type == expected) return true;
161 }
162 // Didn't find the required type in the inheritance chain.
163 return false;
164}
165
166
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000167bool Object::IsSmi() {
168 return HAS_SMI_TAG(this);
169}
170
171
172bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000173 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000174}
175
176
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000177bool Object::NonFailureIsHeapObject() {
178 ASSERT(!this->IsFailure());
179 return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0;
180}
181
182
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000183TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000184
185
186bool Object::IsString() {
187 return Object::IsHeapObject()
188 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
189}
190
191
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000192bool Object::IsSpecObject() {
193 return Object::IsHeapObject()
194 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
195}
196
197
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000198bool Object::IsSpecFunction() {
199 if (!Object::IsHeapObject()) return false;
200 InstanceType type = HeapObject::cast(this)->map()->instance_type();
201 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
202}
203
204
ager@chromium.org870a0b62008-11-04 11:43:05 +0000205bool Object::IsSymbol() {
206 if (!this->IsHeapObject()) return false;
207 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000208 // Because the symbol tag is non-zero and no non-string types have the
209 // symbol bit set we can test for symbols with a very simple test
210 // operation.
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000211 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000212 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
213 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000214}
215
216
217bool Object::IsConsString() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000218 if (!IsString()) return false;
219 return StringShape(String::cast(this)).IsCons();
220}
221
222
223bool Object::IsSlicedString() {
224 if (!IsString()) return false;
225 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000226}
227
228
ager@chromium.org870a0b62008-11-04 11:43:05 +0000229bool Object::IsSeqString() {
230 if (!IsString()) return false;
231 return StringShape(String::cast(this)).IsSequential();
232}
233
234
235bool Object::IsSeqAsciiString() {
236 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000237 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000238 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000239}
240
241
242bool Object::IsSeqTwoByteString() {
243 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000244 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000245 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000246}
247
248
249bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000250 if (!IsString()) return false;
251 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000252}
253
254
255bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000256 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000257 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000258 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000259}
260
261
262bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000263 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000264 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000265 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000266}
267
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000268bool Object::HasValidElements() {
269 // Dictionary is covered under FixedArray.
270 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
271}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000272
ager@chromium.org870a0b62008-11-04 11:43:05 +0000273StringShape::StringShape(String* str)
274 : type_(str->map()->instance_type()) {
275 set_valid();
276 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000277}
278
279
ager@chromium.org870a0b62008-11-04 11:43:05 +0000280StringShape::StringShape(Map* map)
281 : type_(map->instance_type()) {
282 set_valid();
283 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000284}
285
286
ager@chromium.org870a0b62008-11-04 11:43:05 +0000287StringShape::StringShape(InstanceType t)
288 : type_(static_cast<uint32_t>(t)) {
289 set_valid();
290 ASSERT((type_ & kIsNotStringMask) == kStringTag);
291}
292
293
294bool StringShape::IsSymbol() {
295 ASSERT(valid());
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000296 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000297 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000298}
299
300
ager@chromium.org5ec48922009-05-05 07:25:34 +0000301bool String::IsAsciiRepresentation() {
302 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000303 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000304}
305
306
ager@chromium.org5ec48922009-05-05 07:25:34 +0000307bool String::IsTwoByteRepresentation() {
308 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000309 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000310}
311
312
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000313bool String::IsAsciiRepresentationUnderneath() {
314 uint32_t type = map()->instance_type();
315 STATIC_ASSERT(kIsIndirectStringTag != 0);
316 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
317 ASSERT(IsFlat());
318 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
319 case kAsciiStringTag:
320 return true;
321 case kTwoByteStringTag:
322 return false;
323 default: // Cons or sliced string. Need to go deeper.
324 return GetUnderlying()->IsAsciiRepresentation();
325 }
326}
327
328
329bool String::IsTwoByteRepresentationUnderneath() {
330 uint32_t type = map()->instance_type();
331 STATIC_ASSERT(kIsIndirectStringTag != 0);
332 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
333 ASSERT(IsFlat());
334 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
335 case kAsciiStringTag:
336 return false;
337 case kTwoByteStringTag:
338 return true;
339 default: // Cons or sliced string. Need to go deeper.
340 return GetUnderlying()->IsTwoByteRepresentation();
341 }
342}
343
344
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000345bool String::HasOnlyAsciiChars() {
346 uint32_t type = map()->instance_type();
347 return (type & kStringEncodingMask) == kAsciiStringTag ||
348 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000349}
350
351
ager@chromium.org870a0b62008-11-04 11:43:05 +0000352bool StringShape::IsCons() {
353 return (type_ & kStringRepresentationMask) == kConsStringTag;
354}
355
356
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000357bool StringShape::IsSliced() {
358 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
359}
360
361
362bool StringShape::IsIndirect() {
363 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
364}
365
366
ager@chromium.org870a0b62008-11-04 11:43:05 +0000367bool StringShape::IsExternal() {
368 return (type_ & kStringRepresentationMask) == kExternalStringTag;
369}
370
371
372bool StringShape::IsSequential() {
373 return (type_ & kStringRepresentationMask) == kSeqStringTag;
374}
375
376
377StringRepresentationTag StringShape::representation_tag() {
378 uint32_t tag = (type_ & kStringRepresentationMask);
379 return static_cast<StringRepresentationTag>(tag);
380}
381
382
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000383uint32_t StringShape::encoding_tag() {
384 return type_ & kStringEncodingMask;
385}
386
387
ager@chromium.org870a0b62008-11-04 11:43:05 +0000388uint32_t StringShape::full_representation_tag() {
389 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
390}
391
392
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000393STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
394 Internals::kFullStringRepresentationMask);
395
396
ager@chromium.org870a0b62008-11-04 11:43:05 +0000397bool StringShape::IsSequentialAscii() {
398 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
399}
400
401
402bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000403 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000404}
405
406
407bool StringShape::IsExternalAscii() {
408 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
409}
410
411
412bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000413 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000414}
415
416
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000417STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
418 Internals::kExternalTwoByteRepresentationTag);
419
420
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000421uc32 FlatStringReader::Get(int index) {
422 ASSERT(0 <= index && index <= length_);
423 if (is_ascii_) {
424 return static_cast<const byte*>(start_)[index];
425 } else {
426 return static_cast<const uc16*>(start_)[index];
427 }
428}
429
430
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000431bool Object::IsNumber() {
432 return IsSmi() || IsHeapNumber();
433}
434
435
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000436TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
437TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000438
439
440bool Object::IsFiller() {
441 if (!Object::IsHeapObject()) return false;
442 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
443 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
444}
445
446
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000447TYPE_CHECKER(ExternalPixelArray, EXTERNAL_PIXEL_ARRAY_TYPE)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000448
449
ager@chromium.org3811b432009-10-28 14:53:37 +0000450bool Object::IsExternalArray() {
451 if (!Object::IsHeapObject())
452 return false;
453 InstanceType instance_type =
454 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000455 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
456 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000457}
458
459
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000460TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE)
461TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
462TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE)
463TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
464TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE)
465TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
466TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE)
467TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000468
469
lrn@chromium.org303ada72010-10-27 09:33:13 +0000470bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000471 return HAS_FAILURE_TAG(this);
472}
473
474
lrn@chromium.org303ada72010-10-27 09:33:13 +0000475bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000476 return HAS_FAILURE_TAG(this)
477 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
478}
479
480
lrn@chromium.org303ada72010-10-27 09:33:13 +0000481bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000482 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000483 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000484}
485
486
lrn@chromium.org303ada72010-10-27 09:33:13 +0000487bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000488 return this == Failure::Exception();
489}
490
491
lrn@chromium.org303ada72010-10-27 09:33:13 +0000492bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000493 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000494}
495
496
497Failure* Failure::cast(MaybeObject* obj) {
498 ASSERT(HAS_FAILURE_TAG(obj));
499 return reinterpret_cast<Failure*>(obj);
500}
501
502
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000503bool Object::IsJSReceiver() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000504 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000505 return IsHeapObject() &&
506 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
507}
508
509
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000510bool Object::IsJSObject() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000511 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
512 return IsHeapObject() &&
513 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000514}
515
516
517bool Object::IsJSProxy() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000518 if (!Object::IsHeapObject()) return false;
519 InstanceType type = HeapObject::cast(this)->map()->instance_type();
520 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000521}
522
523
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000524TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
525TYPE_CHECKER(JSSet, JS_SET_TYPE)
526TYPE_CHECKER(JSMap, JS_MAP_TYPE)
527TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
528TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
529TYPE_CHECKER(Map, MAP_TYPE)
530TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
531TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000532
533
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000534bool Object::IsDescriptorArray() {
535 return IsFixedArray();
536}
537
538
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000539bool Object::IsDeoptimizationInputData() {
540 // Must be a fixed array.
541 if (!IsFixedArray()) return false;
542
543 // There's no sure way to detect the difference between a fixed array and
544 // a deoptimization data array. Since this is used for asserts we can
545 // check that the length is zero or else the fixed size plus a multiple of
546 // the entry size.
547 int length = FixedArray::cast(this)->length();
548 if (length == 0) return true;
549
550 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
551 return length >= 0 &&
552 length % DeoptimizationInputData::kDeoptEntrySize == 0;
553}
554
555
556bool Object::IsDeoptimizationOutputData() {
557 if (!IsFixedArray()) return false;
558 // There's actually no way to see the difference between a fixed array and
559 // a deoptimization data array. Since this is used for asserts we can check
560 // that the length is plausible though.
561 if (FixedArray::cast(this)->length() % 2 != 0) return false;
562 return true;
563}
564
565
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000566bool Object::IsTypeFeedbackCells() {
567 if (!IsFixedArray()) return false;
568 // There's actually no way to see the difference between a fixed array and
569 // a cache cells array. Since this is used for asserts we can check that
570 // the length is plausible though.
571 if (FixedArray::cast(this)->length() % 2 != 0) return false;
572 return true;
573}
574
575
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000576bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000577 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000578 Map* map = HeapObject::cast(this)->map();
579 Heap* heap = map->GetHeap();
580 return (map == heap->function_context_map() ||
581 map == heap->catch_context_map() ||
582 map == heap->with_context_map() ||
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000583 map == heap->global_context_map() ||
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000584 map == heap->block_context_map() ||
585 map == heap->module_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000586 }
587 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000588}
589
590
591bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000592 return Object::IsHeapObject() &&
593 HeapObject::cast(this)->map() ==
594 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000595}
596
597
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000598bool Object::IsModuleContext() {
599 return Object::IsHeapObject() &&
600 HeapObject::cast(this)->map() ==
601 HeapObject::cast(this)->GetHeap()->module_context_map();
602}
603
604
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000605bool Object::IsScopeInfo() {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000606 return Object::IsHeapObject() &&
607 HeapObject::cast(this)->map() ==
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000608 HeapObject::cast(this)->GetHeap()->scope_info_map();
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000609}
610
611
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000612TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000613
614
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000615template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000616 return obj->IsJSFunction();
617}
618
619
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000620TYPE_CHECKER(Code, CODE_TYPE)
621TYPE_CHECKER(Oddball, ODDBALL_TYPE)
622TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
623TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000624TYPE_CHECKER(JSModule, JS_MODULE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000625TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000626TYPE_CHECKER(JSDate, JS_DATE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000627TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000628
629
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000630bool Object::IsStringWrapper() {
631 return IsJSValue() && JSValue::cast(this)->value()->IsString();
632}
633
634
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000635TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000636
637
638bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000639 return IsOddball() &&
640 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000641}
642
643
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000644TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
645TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000646
647
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000648template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000649 return obj->IsJSArray();
650}
651
652
653bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000654 return Object::IsHeapObject() &&
655 HeapObject::cast(this)->map() ==
656 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000657}
658
659
660bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000661 return IsHashTable() &&
662 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000663}
664
665
666bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000667 return IsHashTable() && this ==
668 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000669}
670
671
ager@chromium.orgac091b72010-05-05 07:34:42 +0000672bool Object::IsJSFunctionResultCache() {
673 if (!IsFixedArray()) return false;
674 FixedArray* self = FixedArray::cast(this);
675 int length = self->length();
676 if (length < JSFunctionResultCache::kEntriesIndex) return false;
677 if ((length - JSFunctionResultCache::kEntriesIndex)
678 % JSFunctionResultCache::kEntrySize != 0) {
679 return false;
680 }
681#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000682 if (FLAG_verify_heap) {
683 reinterpret_cast<JSFunctionResultCache*>(this)->
684 JSFunctionResultCacheVerify();
685 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000686#endif
687 return true;
688}
689
690
ricow@chromium.org65fae842010-08-25 15:26:24 +0000691bool Object::IsNormalizedMapCache() {
692 if (!IsFixedArray()) return false;
693 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
694 return false;
695 }
696#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000697 if (FLAG_verify_heap) {
698 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
699 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000700#endif
701 return true;
702}
703
704
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000705bool Object::IsCompilationCacheTable() {
706 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000707}
708
709
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000710bool Object::IsCodeCacheHashTable() {
711 return IsHashTable();
712}
713
714
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000715bool Object::IsPolymorphicCodeCacheHashTable() {
716 return IsHashTable();
717}
718
719
ager@chromium.org236ad962008-09-25 09:45:57 +0000720bool Object::IsMapCache() {
721 return IsHashTable();
722}
723
724
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000725bool Object::IsPrimitive() {
726 return IsOddball() || IsNumber() || IsString();
727}
728
729
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000730bool Object::IsJSGlobalProxy() {
731 bool result = IsHeapObject() &&
732 (HeapObject::cast(this)->map()->instance_type() ==
733 JS_GLOBAL_PROXY_TYPE);
734 ASSERT(!result || IsAccessCheckNeeded());
735 return result;
736}
737
738
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000739bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000740 if (!IsHeapObject()) return false;
741
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000742 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000743 return type == JS_GLOBAL_OBJECT_TYPE ||
744 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000745}
746
747
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000748TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
749TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000750
751
752bool Object::IsUndetectableObject() {
753 return IsHeapObject()
754 && HeapObject::cast(this)->map()->is_undetectable();
755}
756
757
758bool Object::IsAccessCheckNeeded() {
759 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000760 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000761}
762
763
764bool Object::IsStruct() {
765 if (!IsHeapObject()) return false;
766 switch (HeapObject::cast(this)->map()->instance_type()) {
767#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
768 STRUCT_LIST(MAKE_STRUCT_CASE)
769#undef MAKE_STRUCT_CASE
770 default: return false;
771 }
772}
773
774
775#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
776 bool Object::Is##Name() { \
777 return Object::IsHeapObject() \
778 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
779 }
780 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
781#undef MAKE_STRUCT_PREDICATE
782
783
784bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000785 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000786}
787
788
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000789bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000790 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
791}
792
793
794bool Object::IsTheHole() {
795 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000796}
797
798
799bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000800 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000801}
802
803
804bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000805 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000806}
807
808
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000809bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000810 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000811}
812
813
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000814double Object::Number() {
815 ASSERT(IsNumber());
816 return IsSmi()
817 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
818 : reinterpret_cast<HeapNumber*>(this)->value();
819}
820
821
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000822bool Object::IsNaN() {
823 return this->IsHeapNumber() && isnan(HeapNumber::cast(this)->value());
824}
825
826
lrn@chromium.org303ada72010-10-27 09:33:13 +0000827MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000828 if (IsSmi()) return this;
829 if (IsHeapNumber()) {
830 double value = HeapNumber::cast(this)->value();
831 int int_value = FastD2I(value);
832 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
833 return Smi::FromInt(int_value);
834 }
835 }
836 return Failure::Exception();
837}
838
839
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000840bool Object::HasSpecificClassOf(String* name) {
841 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
842}
843
844
lrn@chromium.org303ada72010-10-27 09:33:13 +0000845MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000846 // GetElement can trigger a getter which can cause allocation.
847 // This was not always the case. This ASSERT is here to catch
848 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000849 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000850 return GetElementWithReceiver(this, index);
851}
852
853
lrn@chromium.org303ada72010-10-27 09:33:13 +0000854Object* Object::GetElementNoExceptionThrown(uint32_t index) {
855 MaybeObject* maybe = GetElementWithReceiver(this, index);
856 ASSERT(!maybe->IsFailure());
857 Object* result = NULL; // Initialization to please compiler.
858 maybe->ToObject(&result);
859 return result;
860}
861
862
863MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000864 PropertyAttributes attributes;
865 return GetPropertyWithReceiver(this, key, &attributes);
866}
867
868
lrn@chromium.org303ada72010-10-27 09:33:13 +0000869MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000870 return GetPropertyWithReceiver(this, key, attributes);
871}
872
873
874#define FIELD_ADDR(p, offset) \
875 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
876
877#define READ_FIELD(p, offset) \
878 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
879
880#define WRITE_FIELD(p, offset, value) \
881 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
882
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000883#define WRITE_BARRIER(heap, object, offset, value) \
884 heap->incremental_marking()->RecordWrite( \
885 object, HeapObject::RawField(object, offset), value); \
886 if (heap->InNewSpace(value)) { \
887 heap->RecordWrite(object->address(), offset); \
888 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000889
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000890#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
891 if (mode == UPDATE_WRITE_BARRIER) { \
892 heap->incremental_marking()->RecordWrite( \
893 object, HeapObject::RawField(object, offset), value); \
894 if (heap->InNewSpace(value)) { \
895 heap->RecordWrite(object->address(), offset); \
896 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000897 }
898
lrn@chromium.org7516f052011-03-30 08:52:27 +0000899#ifndef V8_TARGET_ARCH_MIPS
900 #define READ_DOUBLE_FIELD(p, offset) \
901 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
902#else // V8_TARGET_ARCH_MIPS
903 // Prevent gcc from using load-double (mips ldc1) on (possibly)
904 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000905 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000906 union conversion {
907 double d;
908 uint32_t u[2];
909 } c;
910 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
911 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
912 return c.d;
913 }
914 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
915#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000916
lrn@chromium.org7516f052011-03-30 08:52:27 +0000917#ifndef V8_TARGET_ARCH_MIPS
918 #define WRITE_DOUBLE_FIELD(p, offset, value) \
919 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
920#else // V8_TARGET_ARCH_MIPS
921 // Prevent gcc from using store-double (mips sdc1) on (possibly)
922 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000923 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000924 double value) {
925 union conversion {
926 double d;
927 uint32_t u[2];
928 } c;
929 c.d = value;
930 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
931 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
932 }
933 #define WRITE_DOUBLE_FIELD(p, offset, value) \
934 write_double_field(p, offset, value)
935#endif // V8_TARGET_ARCH_MIPS
936
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000937
938#define READ_INT_FIELD(p, offset) \
939 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
940
941#define WRITE_INT_FIELD(p, offset, value) \
942 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
943
ager@chromium.org3e875802009-06-29 08:26:34 +0000944#define READ_INTPTR_FIELD(p, offset) \
945 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
946
947#define WRITE_INTPTR_FIELD(p, offset, value) \
948 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
949
ager@chromium.org7c537e22008-10-16 08:43:32 +0000950#define READ_UINT32_FIELD(p, offset) \
951 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
952
953#define WRITE_UINT32_FIELD(p, offset, value) \
954 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
955
danno@chromium.org88aa0582012-03-23 15:11:57 +0000956#define READ_INT64_FIELD(p, offset) \
957 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)))
958
959#define WRITE_INT64_FIELD(p, offset, value) \
960 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
961
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000962#define READ_SHORT_FIELD(p, offset) \
963 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
964
965#define WRITE_SHORT_FIELD(p, offset, value) \
966 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
967
968#define READ_BYTE_FIELD(p, offset) \
969 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
970
971#define WRITE_BYTE_FIELD(p, offset, value) \
972 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
973
974
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000975Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
976 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000977}
978
979
980int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000981 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000982}
983
984
985Smi* Smi::FromInt(int value) {
986 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000987 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000988 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000989 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000990 return reinterpret_cast<Smi*>(tagged_value);
991}
992
993
994Smi* Smi::FromIntptr(intptr_t value) {
995 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000996 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
997 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000998}
999
1000
1001Failure::Type Failure::type() const {
1002 return static_cast<Type>(value() & kFailureTypeTagMask);
1003}
1004
1005
1006bool Failure::IsInternalError() const {
1007 return type() == INTERNAL_ERROR;
1008}
1009
1010
1011bool Failure::IsOutOfMemoryException() const {
1012 return type() == OUT_OF_MEMORY_EXCEPTION;
1013}
1014
1015
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001016AllocationSpace Failure::allocation_space() const {
1017 ASSERT_EQ(RETRY_AFTER_GC, type());
1018 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1019 & kSpaceTagMask);
1020}
1021
1022
1023Failure* Failure::InternalError() {
1024 return Construct(INTERNAL_ERROR);
1025}
1026
1027
1028Failure* Failure::Exception() {
1029 return Construct(EXCEPTION);
1030}
1031
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001032
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001033Failure* Failure::OutOfMemoryException() {
1034 return Construct(OUT_OF_MEMORY_EXCEPTION);
1035}
1036
1037
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001038intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001039 return static_cast<intptr_t>(
1040 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001041}
1042
1043
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001044Failure* Failure::RetryAfterGC() {
1045 return RetryAfterGC(NEW_SPACE);
1046}
1047
1048
1049Failure* Failure::RetryAfterGC(AllocationSpace space) {
1050 ASSERT((space & ~kSpaceTagMask) == 0);
1051 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001052}
1053
1054
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001055Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001056 uintptr_t info =
1057 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001058 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001059 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001060}
1061
1062
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001063bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001064#ifdef DEBUG
1065 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1066#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001067
1068#ifdef V8_TARGET_ARCH_X64
1069 // To be representable as a long smi, the value must be a 32-bit integer.
1070 bool result = (value == static_cast<int32_t>(value));
1071#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001072 // To be representable as an tagged small integer, the two
1073 // most-significant bits of 'value' must be either 00 or 11 due to
1074 // sign-extension. To check this we add 01 to the two
1075 // most-significant bits, and check if the most-significant bit is 0
1076 //
1077 // CAUTION: The original code below:
1078 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1079 // may lead to incorrect results according to the C language spec, and
1080 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1081 // compiler may produce undefined results in case of signed integer
1082 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001083 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001084#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001085 ASSERT(result == in_range);
1086 return result;
1087}
1088
1089
kasper.lund7276f142008-07-30 08:49:36 +00001090MapWord MapWord::FromMap(Map* map) {
1091 return MapWord(reinterpret_cast<uintptr_t>(map));
1092}
1093
1094
1095Map* MapWord::ToMap() {
1096 return reinterpret_cast<Map*>(value_);
1097}
1098
1099
1100bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001101 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001102}
1103
1104
1105MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001106 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1107 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001108}
1109
1110
1111HeapObject* MapWord::ToForwardingAddress() {
1112 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001113 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001114}
1115
1116
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001117#ifdef DEBUG
1118void HeapObject::VerifyObjectField(int offset) {
1119 VerifyPointer(READ_FIELD(this, offset));
1120}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001121
1122void HeapObject::VerifySmiField(int offset) {
1123 ASSERT(READ_FIELD(this, offset)->IsSmi());
1124}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001125#endif
1126
1127
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001128Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001129 Heap* heap =
1130 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1131 ASSERT(heap != NULL);
1132 ASSERT(heap->isolate() == Isolate::Current());
1133 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001134}
1135
1136
1137Isolate* HeapObject::GetIsolate() {
1138 return GetHeap()->isolate();
1139}
1140
1141
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001142Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001143 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001144}
1145
1146
1147void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001148 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001149 if (value != NULL) {
1150 // TODO(1600) We are passing NULL as a slot because maps can never be on
1151 // evacuation candidate.
1152 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1153 }
1154}
1155
1156
1157// Unsafe accessor omitting write barrier.
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001158void HeapObject::set_map_no_write_barrier(Map* value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001159 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001160}
1161
1162
kasper.lund7276f142008-07-30 08:49:36 +00001163MapWord HeapObject::map_word() {
1164 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1165}
1166
1167
1168void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001169 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001170 // here.
1171 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1172}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001173
1174
1175HeapObject* HeapObject::FromAddress(Address address) {
1176 ASSERT_TAG_ALIGNED(address);
1177 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1178}
1179
1180
1181Address HeapObject::address() {
1182 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1183}
1184
1185
1186int HeapObject::Size() {
1187 return SizeFromMap(map());
1188}
1189
1190
1191void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1192 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1193 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1194}
1195
1196
1197void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1198 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1199}
1200
1201
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001202double HeapNumber::value() {
1203 return READ_DOUBLE_FIELD(this, kValueOffset);
1204}
1205
1206
1207void HeapNumber::set_value(double value) {
1208 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1209}
1210
1211
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001212int HeapNumber::get_exponent() {
1213 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1214 kExponentShift) - kExponentBias;
1215}
1216
1217
1218int HeapNumber::get_sign() {
1219 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1220}
1221
1222
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001223ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001224
1225
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001226Object** FixedArray::GetFirstElementAddress() {
1227 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1228}
1229
1230
1231bool FixedArray::ContainsOnlySmisOrHoles() {
1232 Object* the_hole = GetHeap()->the_hole_value();
1233 Object** current = GetFirstElementAddress();
1234 for (int i = 0; i < length(); ++i) {
1235 Object* candidate = *current++;
1236 if (!candidate->IsSmi() && candidate != the_hole) return false;
1237 }
1238 return true;
1239}
1240
1241
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001242FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001243 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001244 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001245}
1246
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001247void JSObject::ValidateSmiOnlyElements() {
1248#if DEBUG
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001249 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001250 Heap* heap = GetHeap();
1251 // Don't use elements, since integrity checks will fail if there
1252 // are filler pointers in the array.
1253 FixedArray* fixed_array =
1254 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
1255 Map* map = fixed_array->map();
1256 // Arrays that have been shifted in place can't be verified.
1257 if (map != heap->raw_unchecked_one_pointer_filler_map() &&
1258 map != heap->raw_unchecked_two_pointer_filler_map() &&
1259 map != heap->free_space_map()) {
1260 for (int i = 0; i < fixed_array->length(); i++) {
1261 Object* current = fixed_array->get(i);
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001262 ASSERT(current->IsSmi() || current->IsTheHole());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001263 }
1264 }
1265 }
1266#endif
1267}
1268
1269
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001270MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001271#if DEBUG
1272 ValidateSmiOnlyElements();
1273#endif
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001274 if ((map()->elements_kind() != FAST_ELEMENTS)) {
1275 return TransitionElementsKind(FAST_ELEMENTS);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001276 }
1277 return this;
1278}
1279
1280
1281MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001282 uint32_t count,
1283 EnsureElementsMode mode) {
1284 ElementsKind current_kind = map()->elements_kind();
1285 ElementsKind target_kind = current_kind;
1286 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
1287 if (current_kind == FAST_ELEMENTS) return this;
1288
1289 Heap* heap = GetHeap();
1290 Object* the_hole = heap->the_hole_value();
1291 Object* heap_number_map = heap->heap_number_map();
1292 for (uint32_t i = 0; i < count; ++i) {
1293 Object* current = *objects++;
1294 if (!current->IsSmi() && current != the_hole) {
1295 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS &&
1296 HeapObject::cast(current)->map() == heap_number_map) {
1297 target_kind = FAST_DOUBLE_ELEMENTS;
1298 } else {
1299 target_kind = FAST_ELEMENTS;
1300 break;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001301 }
1302 }
1303 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001304
1305 if (target_kind != current_kind) {
1306 return TransitionElementsKind(target_kind);
1307 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001308 return this;
1309}
1310
1311
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001312MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
1313 EnsureElementsMode mode) {
1314 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1315 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1316 elements->map() == GetHeap()->fixed_cow_array_map());
1317 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1318 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1319 }
1320 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
1321 return EnsureCanContainElements(objects, elements->length(), mode);
1322 }
1323
1324 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
1325 if (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) {
1326 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1327 }
1328
1329 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001330}
1331
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001332
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001333MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
1334 ElementsKind to_kind) {
1335 Map* current_map = map();
1336 ElementsKind from_kind = current_map->elements_kind();
1337
1338 if (from_kind == to_kind) return current_map;
1339
1340 Context* global_context = isolate->context()->global_context();
1341 if (current_map == global_context->smi_js_array_map()) {
1342 if (to_kind == FAST_ELEMENTS) {
1343 return global_context->object_js_array_map();
1344 } else {
1345 if (to_kind == FAST_DOUBLE_ELEMENTS) {
1346 return global_context->double_js_array_map();
1347 } else {
1348 ASSERT(to_kind == DICTIONARY_ELEMENTS);
1349 }
1350 }
1351 }
1352 return GetElementsTransitionMapSlow(to_kind);
1353}
1354
1355
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001356void JSObject::set_map_and_elements(Map* new_map,
1357 FixedArrayBase* value,
1358 WriteBarrierMode mode) {
1359 ASSERT(value->HasValidElements());
1360#ifdef DEBUG
1361 ValidateSmiOnlyElements();
1362#endif
1363 if (new_map != NULL) {
1364 if (mode == UPDATE_WRITE_BARRIER) {
1365 set_map(new_map);
1366 } else {
1367 ASSERT(mode == SKIP_WRITE_BARRIER);
1368 set_map_no_write_barrier(new_map);
1369 }
1370 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001371 ASSERT((map()->has_fast_elements() ||
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001372 map()->has_fast_smi_only_elements() ||
1373 (value == GetHeap()->empty_fixed_array())) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001374 (value->map() == GetHeap()->fixed_array_map() ||
1375 value->map() == GetHeap()->fixed_cow_array_map()));
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001376 ASSERT((value == GetHeap()->empty_fixed_array()) ||
1377 (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001378 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001379 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001380}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001381
1382
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001383void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1384 set_map_and_elements(NULL, value, mode);
1385}
1386
1387
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001388void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001389 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1390 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001391}
1392
1393
1394void JSObject::initialize_elements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001395 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001396 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1397 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001398}
1399
1400
lrn@chromium.org303ada72010-10-27 09:33:13 +00001401MaybeObject* JSObject::ResetElements() {
1402 Object* obj;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001403 ElementsKind elements_kind = FLAG_smi_only_arrays
1404 ? FAST_SMI_ONLY_ELEMENTS
1405 : FAST_ELEMENTS;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001406 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(),
1407 elements_kind);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001408 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001409 set_map(Map::cast(obj));
1410 initialize_elements();
1411 return this;
1412}
1413
1414
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001415ACCESSORS(Oddball, to_string, String, kToStringOffset)
1416ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1417
1418
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001419byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001420 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001421}
1422
1423
1424void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001425 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001426}
1427
1428
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001429Object* JSGlobalPropertyCell::value() {
1430 return READ_FIELD(this, kValueOffset);
1431}
1432
1433
1434void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1435 // The write barrier is not used for global property cells.
1436 ASSERT(!val->IsJSGlobalPropertyCell());
1437 WRITE_FIELD(this, kValueOffset, val);
1438}
1439
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001440
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001441int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001442 InstanceType type = map()->instance_type();
1443 // Check for the most common kind of JavaScript object before
1444 // falling into the generic switch. This speeds up the internal
1445 // field operations considerably on average.
1446 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1447 switch (type) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001448 case JS_MODULE_TYPE:
1449 return JSModule::kSize;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001450 case JS_GLOBAL_PROXY_TYPE:
1451 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001452 case JS_GLOBAL_OBJECT_TYPE:
1453 return JSGlobalObject::kSize;
1454 case JS_BUILTINS_OBJECT_TYPE:
1455 return JSBuiltinsObject::kSize;
1456 case JS_FUNCTION_TYPE:
1457 return JSFunction::kSize;
1458 case JS_VALUE_TYPE:
1459 return JSValue::kSize;
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00001460 case JS_DATE_TYPE:
1461 return JSDate::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001462 case JS_ARRAY_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001463 return JSArray::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001464 case JS_WEAK_MAP_TYPE:
1465 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001466 case JS_REGEXP_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001467 return JSRegExp::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001468 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001469 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001470 case JS_MESSAGE_OBJECT_TYPE:
1471 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001472 default:
1473 UNREACHABLE();
1474 return 0;
1475 }
1476}
1477
1478
1479int JSObject::GetInternalFieldCount() {
1480 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001481 // Make sure to adjust for the number of in-object properties. These
1482 // properties do contribute to the size, but are not internal fields.
1483 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1484 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001485}
1486
1487
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001488int JSObject::GetInternalFieldOffset(int index) {
1489 ASSERT(index < GetInternalFieldCount() && index >= 0);
1490 return GetHeaderSize() + (kPointerSize * index);
1491}
1492
1493
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001494Object* JSObject::GetInternalField(int index) {
1495 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001496 // Internal objects do follow immediately after the header, whereas in-object
1497 // properties are at the end of the object. Therefore there is no need
1498 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001499 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1500}
1501
1502
1503void JSObject::SetInternalField(int index, Object* value) {
1504 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001505 // Internal objects do follow immediately after the header, whereas in-object
1506 // properties are at the end of the object. Therefore there is no need
1507 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001508 int offset = GetHeaderSize() + (kPointerSize * index);
1509 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001510 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001511}
1512
1513
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001514void JSObject::SetInternalField(int index, Smi* value) {
1515 ASSERT(index < GetInternalFieldCount() && index >= 0);
1516 // Internal objects do follow immediately after the header, whereas in-object
1517 // properties are at the end of the object. Therefore there is no need
1518 // to adjust the index here.
1519 int offset = GetHeaderSize() + (kPointerSize * index);
1520 WRITE_FIELD(this, offset, value);
1521}
1522
1523
ager@chromium.org7c537e22008-10-16 08:43:32 +00001524// Access fast-case object properties at index. The use of these routines
1525// is needed to correctly distinguish between properties stored in-object and
1526// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001527Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001528 // Adjust for the number of properties stored in the object.
1529 index -= map()->inobject_properties();
1530 if (index < 0) {
1531 int offset = map()->instance_size() + (index * kPointerSize);
1532 return READ_FIELD(this, offset);
1533 } else {
1534 ASSERT(index < properties()->length());
1535 return properties()->get(index);
1536 }
1537}
1538
1539
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001540Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001541 // Adjust for the number of properties stored in the object.
1542 index -= map()->inobject_properties();
1543 if (index < 0) {
1544 int offset = map()->instance_size() + (index * kPointerSize);
1545 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001546 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001547 } else {
1548 ASSERT(index < properties()->length());
1549 properties()->set(index, value);
1550 }
1551 return value;
1552}
1553
1554
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001555int JSObject::GetInObjectPropertyOffset(int index) {
1556 // Adjust for the number of properties stored in the object.
1557 index -= map()->inobject_properties();
1558 ASSERT(index < 0);
1559 return map()->instance_size() + (index * kPointerSize);
1560}
1561
1562
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001563Object* JSObject::InObjectPropertyAt(int index) {
1564 // Adjust for the number of properties stored in the object.
1565 index -= map()->inobject_properties();
1566 ASSERT(index < 0);
1567 int offset = map()->instance_size() + (index * kPointerSize);
1568 return READ_FIELD(this, offset);
1569}
1570
1571
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001572Object* JSObject::InObjectPropertyAtPut(int index,
1573 Object* value,
1574 WriteBarrierMode mode) {
1575 // Adjust for the number of properties stored in the object.
1576 index -= map()->inobject_properties();
1577 ASSERT(index < 0);
1578 int offset = map()->instance_size() + (index * kPointerSize);
1579 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001580 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001581 return value;
1582}
1583
1584
1585
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001586void JSObject::InitializeBody(Map* map,
1587 Object* pre_allocated_value,
1588 Object* filler_value) {
1589 ASSERT(!filler_value->IsHeapObject() ||
1590 !GetHeap()->InNewSpace(filler_value));
1591 ASSERT(!pre_allocated_value->IsHeapObject() ||
1592 !GetHeap()->InNewSpace(pre_allocated_value));
1593 int size = map->instance_size();
1594 int offset = kHeaderSize;
1595 if (filler_value != pre_allocated_value) {
1596 int pre_allocated = map->pre_allocated_property_fields();
1597 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1598 for (int i = 0; i < pre_allocated; i++) {
1599 WRITE_FIELD(this, offset, pre_allocated_value);
1600 offset += kPointerSize;
1601 }
1602 }
1603 while (offset < size) {
1604 WRITE_FIELD(this, offset, filler_value);
1605 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001606 }
1607}
1608
1609
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001610bool JSObject::HasFastProperties() {
1611 return !properties()->IsDictionary();
1612}
1613
1614
1615int JSObject::MaxFastProperties() {
1616 // Allow extra fast properties if the object has more than
1617 // kMaxFastProperties in-object properties. When this is the case,
1618 // it is very unlikely that the object is being used as a dictionary
1619 // and there is a good chance that allowing more map transitions
1620 // will be worth it.
1621 return Max(map()->inobject_properties(), kMaxFastProperties);
1622}
1623
1624
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001625void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001626 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001627 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001628 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001629 }
1630}
1631
1632
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001633bool Object::ToArrayIndex(uint32_t* index) {
1634 if (IsSmi()) {
1635 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001636 if (value < 0) return false;
1637 *index = value;
1638 return true;
1639 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001640 if (IsHeapNumber()) {
1641 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001642 uint32_t uint_value = static_cast<uint32_t>(value);
1643 if (value == static_cast<double>(uint_value)) {
1644 *index = uint_value;
1645 return true;
1646 }
1647 }
1648 return false;
1649}
1650
1651
1652bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1653 if (!this->IsJSValue()) return false;
1654
1655 JSValue* js_value = JSValue::cast(this);
1656 if (!js_value->value()->IsString()) return false;
1657
1658 String* str = String::cast(js_value->value());
1659 if (index >= (uint32_t)str->length()) return false;
1660
1661 return true;
1662}
1663
1664
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001665FixedArrayBase* FixedArrayBase::cast(Object* object) {
1666 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1667 return reinterpret_cast<FixedArrayBase*>(object);
1668}
1669
1670
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001671Object* FixedArray::get(int index) {
1672 ASSERT(index >= 0 && index < this->length());
1673 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1674}
1675
1676
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001677void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001678 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001679 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001680 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1681 int offset = kHeaderSize + index * kPointerSize;
1682 WRITE_FIELD(this, offset, value);
1683}
1684
1685
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001686void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001687 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001688 ASSERT(index >= 0 && index < this->length());
1689 int offset = kHeaderSize + index * kPointerSize;
1690 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001691 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001692}
1693
1694
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001695inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1696 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1697}
1698
1699
1700inline double FixedDoubleArray::hole_nan_as_double() {
1701 return BitCast<double, uint64_t>(kHoleNanInt64);
1702}
1703
1704
1705inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1706 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1707 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1708 return OS::nan_value();
1709}
1710
1711
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001712double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001713 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1714 map() != HEAP->fixed_array_map());
1715 ASSERT(index >= 0 && index < this->length());
1716 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1717 ASSERT(!is_the_hole_nan(result));
1718 return result;
1719}
1720
danno@chromium.org88aa0582012-03-23 15:11:57 +00001721int64_t FixedDoubleArray::get_representation(int index) {
1722 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1723 map() != HEAP->fixed_array_map());
1724 ASSERT(index >= 0 && index < this->length());
1725 return READ_INT64_FIELD(this, kHeaderSize + index * kDoubleSize);
1726}
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001727
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001728MaybeObject* FixedDoubleArray::get(int index) {
1729 if (is_the_hole(index)) {
1730 return GetHeap()->the_hole_value();
1731 } else {
1732 return GetHeap()->NumberFromDouble(get_scalar(index));
1733 }
1734}
1735
1736
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001737void FixedDoubleArray::set(int index, double value) {
1738 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1739 map() != HEAP->fixed_array_map());
1740 int offset = kHeaderSize + index * kDoubleSize;
1741 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1742 WRITE_DOUBLE_FIELD(this, offset, value);
1743}
1744
1745
1746void FixedDoubleArray::set_the_hole(int index) {
1747 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1748 map() != HEAP->fixed_array_map());
1749 int offset = kHeaderSize + index * kDoubleSize;
1750 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1751}
1752
1753
1754bool FixedDoubleArray::is_the_hole(int index) {
1755 int offset = kHeaderSize + index * kDoubleSize;
1756 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1757}
1758
1759
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001760WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001761 Heap* heap = GetHeap();
1762 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1763 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001764 return UPDATE_WRITE_BARRIER;
1765}
1766
1767
1768void FixedArray::set(int index,
1769 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001770 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001771 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001772 ASSERT(index >= 0 && index < this->length());
1773 int offset = kHeaderSize + index * kPointerSize;
1774 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001775 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001776}
1777
1778
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001779void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1780 int index,
1781 Object* value) {
1782 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
1783 ASSERT(index >= 0 && index < array->length());
1784 int offset = kHeaderSize + index * kPointerSize;
1785 WRITE_FIELD(array, offset, value);
1786 Heap* heap = array->GetHeap();
1787 if (heap->InNewSpace(value)) {
1788 heap->RecordWrite(array->address(), offset);
1789 }
1790}
1791
1792
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001793void FixedArray::NoWriteBarrierSet(FixedArray* array,
1794 int index,
1795 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001796 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001797 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001798 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001799 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1800}
1801
1802
1803void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001804 ASSERT(map() != HEAP->fixed_cow_array_map());
1805 set_undefined(GetHeap(), index);
1806}
1807
1808
1809void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001810 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001811 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001812 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001813 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001814}
1815
1816
ager@chromium.org236ad962008-09-25 09:45:57 +00001817void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001818 set_null(GetHeap(), index);
1819}
1820
1821
1822void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001823 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001824 ASSERT(!heap->InNewSpace(heap->null_value()));
1825 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001826}
1827
1828
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001829void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001830 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001831 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001832 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1833 WRITE_FIELD(this,
1834 kHeaderSize + index * kPointerSize,
1835 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001836}
1837
1838
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001839void FixedArray::set_unchecked(int index, Smi* value) {
1840 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1841 int offset = kHeaderSize + index * kPointerSize;
1842 WRITE_FIELD(this, offset, value);
1843}
1844
1845
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001846void FixedArray::set_unchecked(Heap* heap,
1847 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001848 Object* value,
1849 WriteBarrierMode mode) {
1850 int offset = kHeaderSize + index * kPointerSize;
1851 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001852 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001853}
1854
1855
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001856void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001857 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001858 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1859 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001860}
1861
1862
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001863Object** FixedArray::data_start() {
1864 return HeapObject::RawField(this, kHeaderSize);
1865}
1866
1867
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001868bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001869 ASSERT(this->IsSmi() ||
1870 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001871 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001872 return this->IsSmi() || length() <= kFirstIndex;
1873}
1874
1875
1876int DescriptorArray::bit_field3_storage() {
1877 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1878 return Smi::cast(storage)->value();
1879}
1880
1881void DescriptorArray::set_bit_field3_storage(int value) {
1882 ASSERT(!IsEmpty());
1883 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001884}
1885
1886
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001887void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1888 int first,
1889 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001890 Object* tmp = array->get(first);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001891 NoIncrementalWriteBarrierSet(array, first, array->get(second));
1892 NoIncrementalWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001893}
1894
1895
1896int DescriptorArray::Search(String* name) {
1897 SLOW_ASSERT(IsSortedNoDuplicates());
1898
1899 // Check for empty descriptor array.
1900 int nof = number_of_descriptors();
1901 if (nof == 0) return kNotFound;
1902
1903 // Fast case: do linear search for small arrays.
1904 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001905 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001906 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001907 }
1908
1909 // Slow case: perform binary search.
1910 return BinarySearch(name, 0, nof - 1);
1911}
1912
1913
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001914int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001915 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001916 if (number == DescriptorLookupCache::kAbsent) {
1917 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001918 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001919 }
1920 return number;
1921}
1922
1923
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001924String* DescriptorArray::GetKey(int descriptor_number) {
1925 ASSERT(descriptor_number < number_of_descriptors());
1926 return String::cast(get(ToKeyIndex(descriptor_number)));
1927}
1928
1929
1930Object* DescriptorArray::GetValue(int descriptor_number) {
1931 ASSERT(descriptor_number < number_of_descriptors());
1932 return GetContentArray()->get(ToValueIndex(descriptor_number));
1933}
1934
1935
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001936PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001937 ASSERT(descriptor_number < number_of_descriptors());
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001938 Object* details = GetContentArray()->get(ToDetailsIndex(descriptor_number));
1939 return PropertyDetails(Smi::cast(details));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001940}
1941
1942
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001943PropertyType DescriptorArray::GetType(int descriptor_number) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001944 return GetDetails(descriptor_number).type();
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001945}
1946
1947
1948int DescriptorArray::GetFieldIndex(int descriptor_number) {
1949 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1950}
1951
1952
1953JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1954 return JSFunction::cast(GetValue(descriptor_number));
1955}
1956
1957
1958Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1959 ASSERT(GetType(descriptor_number) == CALLBACKS);
1960 return GetValue(descriptor_number);
1961}
1962
1963
1964AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1965 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001966 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001967 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001968}
1969
1970
1971bool DescriptorArray::IsProperty(int descriptor_number) {
ulan@chromium.org9a21ec42012-03-06 08:42:24 +00001972 Entry entry(this, descriptor_number);
1973 return IsPropertyDescriptor(&entry);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001974}
1975
1976
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001977bool DescriptorArray::IsTransitionOnly(int descriptor_number) {
1978 switch (GetType(descriptor_number)) {
1979 case MAP_TRANSITION:
1980 case CONSTANT_TRANSITION:
1981 case ELEMENTS_TRANSITION:
1982 return true;
1983 case CALLBACKS: {
1984 Object* value = GetValue(descriptor_number);
1985 if (!value->IsAccessorPair()) return false;
1986 AccessorPair* accessors = AccessorPair::cast(value);
1987 return accessors->getter()->IsMap() && accessors->setter()->IsMap();
1988 }
1989 case NORMAL:
1990 case FIELD:
1991 case CONSTANT_FUNCTION:
1992 case HANDLER:
1993 case INTERCEPTOR:
1994 case NULL_DESCRIPTOR:
1995 return false;
1996 }
1997 UNREACHABLE(); // Keep the compiler happy.
1998 return false;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001999}
2000
2001
2002bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
2003 return GetType(descriptor_number) == NULL_DESCRIPTOR;
2004}
2005
2006
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002007void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2008 desc->Init(GetKey(descriptor_number),
2009 GetValue(descriptor_number),
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002010 GetDetails(descriptor_number));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002011}
2012
2013
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002014void DescriptorArray::Set(int descriptor_number,
2015 Descriptor* desc,
2016 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002017 // Range check.
2018 ASSERT(descriptor_number < number_of_descriptors());
2019
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002020 NoIncrementalWriteBarrierSet(this,
2021 ToKeyIndex(descriptor_number),
2022 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002023 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002024 NoIncrementalWriteBarrierSet(content_array,
2025 ToValueIndex(descriptor_number),
2026 desc->GetValue());
2027 NoIncrementalWriteBarrierSet(content_array,
2028 ToDetailsIndex(descriptor_number),
2029 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002030}
2031
2032
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002033void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2034 int first, int second) {
2035 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002036 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002037 NoIncrementalWriteBarrierSwap(content_array,
2038 ToValueIndex(first),
2039 ToValueIndex(second));
2040 NoIncrementalWriteBarrierSwap(content_array,
2041 ToDetailsIndex(first),
2042 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002043}
2044
2045
2046DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
2047 : marking_(array->GetHeap()->incremental_marking()) {
2048 marking_->EnterNoMarkingScope();
2049 if (array->number_of_descriptors() > 0) {
2050 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
2051 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
2052 }
2053}
2054
2055
2056DescriptorArray::WhitenessWitness::~WhitenessWitness() {
2057 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002058}
2059
2060
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002061template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002062int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2063 const int kMinCapacity = 32;
2064 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2065 if (capacity < kMinCapacity) {
2066 capacity = kMinCapacity; // Guarantee min capacity.
2067 }
2068 return capacity;
2069}
2070
2071
2072template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002073int HashTable<Shape, Key>::FindEntry(Key key) {
2074 return FindEntry(GetIsolate(), key);
2075}
2076
2077
2078// Find entry for key otherwise return kNotFound.
2079template<typename Shape, typename Key>
2080int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2081 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002082 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002083 uint32_t count = 1;
2084 // EnsureCapacity will guarantee the hash table is never full.
2085 while (true) {
2086 Object* element = KeyAt(entry);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002087 // Empty entry.
2088 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2089 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002090 Shape::IsMatch(key, element)) return entry;
2091 entry = NextProbe(entry, count++, capacity);
2092 }
2093 return kNotFound;
2094}
2095
2096
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002097bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002098 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002099 if (!max_index_object->IsSmi()) return false;
2100 return 0 !=
2101 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2102}
2103
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002104uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002105 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002106 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002107 if (!max_index_object->IsSmi()) return 0;
2108 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2109 return value >> kRequiresSlowElementsTagSize;
2110}
2111
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002112void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002113 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002114}
2115
2116
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002117// ------------------------------------
2118// Cast operations
2119
2120
2121CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002122CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002123CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002124CAST_ACCESSOR(DeoptimizationInputData)
2125CAST_ACCESSOR(DeoptimizationOutputData)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002126CAST_ACCESSOR(TypeFeedbackCells)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002127CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002128CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002129CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002130CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002131CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002132CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002133CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002134CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002135CAST_ACCESSOR(String)
2136CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002137CAST_ACCESSOR(SeqAsciiString)
2138CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002139CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002140CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002141CAST_ACCESSOR(ExternalString)
2142CAST_ACCESSOR(ExternalAsciiString)
2143CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002144CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002145CAST_ACCESSOR(JSObject)
2146CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002147CAST_ACCESSOR(HeapObject)
2148CAST_ACCESSOR(HeapNumber)
2149CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002150CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002151CAST_ACCESSOR(SharedFunctionInfo)
2152CAST_ACCESSOR(Map)
2153CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002154CAST_ACCESSOR(GlobalObject)
2155CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002156CAST_ACCESSOR(JSGlobalObject)
2157CAST_ACCESSOR(JSBuiltinsObject)
2158CAST_ACCESSOR(Code)
2159CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002160CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002161CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002162CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002163CAST_ACCESSOR(JSSet)
2164CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002165CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002166CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002167CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002168CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002169CAST_ACCESSOR(ExternalArray)
2170CAST_ACCESSOR(ExternalByteArray)
2171CAST_ACCESSOR(ExternalUnsignedByteArray)
2172CAST_ACCESSOR(ExternalShortArray)
2173CAST_ACCESSOR(ExternalUnsignedShortArray)
2174CAST_ACCESSOR(ExternalIntArray)
2175CAST_ACCESSOR(ExternalUnsignedIntArray)
2176CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002177CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002178CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002179CAST_ACCESSOR(Struct)
2180
2181
2182#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2183 STRUCT_LIST(MAKE_STRUCT_CAST)
2184#undef MAKE_STRUCT_CAST
2185
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002186
2187template <typename Shape, typename Key>
2188HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002189 ASSERT(obj->IsHashTable());
2190 return reinterpret_cast<HashTable*>(obj);
2191}
2192
2193
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002194SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002195SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002196
ager@chromium.orgac091b72010-05-05 07:34:42 +00002197SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002198
2199
2200uint32_t String::hash_field() {
2201 return READ_UINT32_FIELD(this, kHashFieldOffset);
2202}
2203
2204
2205void String::set_hash_field(uint32_t value) {
2206 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002207#if V8_HOST_ARCH_64_BIT
2208 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2209#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002210}
2211
2212
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002213bool String::Equals(String* other) {
2214 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002215 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2216 return false;
2217 }
2218 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002219}
2220
2221
lrn@chromium.org303ada72010-10-27 09:33:13 +00002222MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002223 if (!StringShape(this).IsCons()) return this;
2224 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002225 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002226 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002227}
2228
2229
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002230String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002231 MaybeObject* flat = TryFlatten(pretenure);
2232 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002233 if (!flat->ToObject(&successfully_flattened)) return this;
2234 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002235}
2236
2237
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002238uint16_t String::Get(int index) {
2239 ASSERT(index >= 0 && index < length());
2240 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002241 case kSeqStringTag | kAsciiStringTag:
2242 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2243 case kSeqStringTag | kTwoByteStringTag:
2244 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2245 case kConsStringTag | kAsciiStringTag:
2246 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002247 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002248 case kExternalStringTag | kAsciiStringTag:
2249 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2250 case kExternalStringTag | kTwoByteStringTag:
2251 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002252 case kSlicedStringTag | kAsciiStringTag:
2253 case kSlicedStringTag | kTwoByteStringTag:
2254 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002255 default:
2256 break;
2257 }
2258
2259 UNREACHABLE();
2260 return 0;
2261}
2262
2263
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002264void String::Set(int index, uint16_t value) {
2265 ASSERT(index >= 0 && index < length());
2266 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002267
ager@chromium.org5ec48922009-05-05 07:25:34 +00002268 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002269 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2270 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002271}
2272
2273
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002274bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002275 if (!StringShape(this).IsCons()) return true;
2276 return ConsString::cast(this)->second()->length() == 0;
2277}
2278
2279
2280String* String::GetUnderlying() {
2281 // Giving direct access to underlying string only makes sense if the
2282 // wrapping string is already flattened.
2283 ASSERT(this->IsFlat());
2284 ASSERT(StringShape(this).IsIndirect());
2285 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2286 const int kUnderlyingOffset = SlicedString::kParentOffset;
2287 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002288}
2289
2290
ager@chromium.org7c537e22008-10-16 08:43:32 +00002291uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002292 ASSERT(index >= 0 && index < length());
2293 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2294}
2295
2296
ager@chromium.org7c537e22008-10-16 08:43:32 +00002297void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002298 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2299 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2300 static_cast<byte>(value));
2301}
2302
2303
ager@chromium.org7c537e22008-10-16 08:43:32 +00002304Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002305 return FIELD_ADDR(this, kHeaderSize);
2306}
2307
2308
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002309char* SeqAsciiString::GetChars() {
2310 return reinterpret_cast<char*>(GetCharsAddress());
2311}
2312
2313
ager@chromium.org7c537e22008-10-16 08:43:32 +00002314Address SeqTwoByteString::GetCharsAddress() {
2315 return FIELD_ADDR(this, kHeaderSize);
2316}
2317
2318
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002319uc16* SeqTwoByteString::GetChars() {
2320 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2321}
2322
2323
ager@chromium.org7c537e22008-10-16 08:43:32 +00002324uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002325 ASSERT(index >= 0 && index < length());
2326 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2327}
2328
2329
ager@chromium.org7c537e22008-10-16 08:43:32 +00002330void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002331 ASSERT(index >= 0 && index < length());
2332 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2333}
2334
2335
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002336int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002337 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002338}
2339
2340
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002341int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002342 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002343}
2344
2345
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002346String* SlicedString::parent() {
2347 return String::cast(READ_FIELD(this, kParentOffset));
2348}
2349
2350
2351void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002352 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002353 WRITE_FIELD(this, kParentOffset, parent);
2354}
2355
2356
2357SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2358
2359
ager@chromium.org870a0b62008-11-04 11:43:05 +00002360String* ConsString::first() {
2361 return String::cast(READ_FIELD(this, kFirstOffset));
2362}
2363
2364
2365Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002366 return READ_FIELD(this, kFirstOffset);
2367}
2368
2369
ager@chromium.org870a0b62008-11-04 11:43:05 +00002370void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002371 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002372 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002373}
2374
2375
ager@chromium.org870a0b62008-11-04 11:43:05 +00002376String* ConsString::second() {
2377 return String::cast(READ_FIELD(this, kSecondOffset));
2378}
2379
2380
2381Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002382 return READ_FIELD(this, kSecondOffset);
2383}
2384
2385
ager@chromium.org870a0b62008-11-04 11:43:05 +00002386void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002387 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002388 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002389}
2390
2391
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002392bool ExternalString::is_short() {
2393 InstanceType type = map()->instance_type();
2394 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002395}
2396
2397
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002398const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002399 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2400}
2401
2402
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002403void ExternalAsciiString::update_data_cache() {
2404 if (is_short()) return;
2405 const char** data_field =
2406 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2407 *data_field = resource()->data();
2408}
2409
2410
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002411void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002412 const ExternalAsciiString::Resource* resource) {
2413 *reinterpret_cast<const Resource**>(
2414 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002415 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002416}
2417
2418
2419const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002420 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002421}
2422
2423
2424uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2425 ASSERT(index >= 0 && index < length());
2426 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002427}
2428
2429
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002430const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002431 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2432}
2433
2434
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002435void ExternalTwoByteString::update_data_cache() {
2436 if (is_short()) return;
2437 const uint16_t** data_field =
2438 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2439 *data_field = resource()->data();
2440}
2441
2442
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002443void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002444 const ExternalTwoByteString::Resource* resource) {
2445 *reinterpret_cast<const Resource**>(
2446 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002447 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002448}
2449
2450
2451const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002452 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002453}
2454
2455
2456uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2457 ASSERT(index >= 0 && index < length());
2458 return GetChars()[index];
2459}
2460
2461
2462const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2463 unsigned start) {
2464 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002465}
2466
2467
ager@chromium.orgac091b72010-05-05 07:34:42 +00002468void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002469 set_finger_index(kEntriesIndex);
2470 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002471}
2472
2473
2474void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002475 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002476 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002477 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002478 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002479 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002480 MakeZeroSize();
2481}
2482
2483
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002484int JSFunctionResultCache::size() {
2485 return Smi::cast(get(kCacheSizeIndex))->value();
2486}
2487
2488
2489void JSFunctionResultCache::set_size(int size) {
2490 set(kCacheSizeIndex, Smi::FromInt(size));
2491}
2492
2493
2494int JSFunctionResultCache::finger_index() {
2495 return Smi::cast(get(kFingerIndex))->value();
2496}
2497
2498
2499void JSFunctionResultCache::set_finger_index(int finger_index) {
2500 set(kFingerIndex, Smi::FromInt(finger_index));
2501}
2502
2503
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002504byte ByteArray::get(int index) {
2505 ASSERT(index >= 0 && index < this->length());
2506 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2507}
2508
2509
2510void ByteArray::set(int index, byte value) {
2511 ASSERT(index >= 0 && index < this->length());
2512 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2513}
2514
2515
2516int ByteArray::get_int(int index) {
2517 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2518 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2519}
2520
2521
2522ByteArray* ByteArray::FromDataStartAddress(Address address) {
2523 ASSERT_TAG_ALIGNED(address);
2524 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2525}
2526
2527
2528Address ByteArray::GetDataStartAddress() {
2529 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2530}
2531
2532
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002533uint8_t* ExternalPixelArray::external_pixel_pointer() {
2534 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002535}
2536
2537
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002538uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002539 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002540 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002541 return ptr[index];
2542}
2543
2544
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002545MaybeObject* ExternalPixelArray::get(int index) {
2546 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2547}
2548
2549
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002550void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002551 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002552 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002553 ptr[index] = value;
2554}
2555
2556
ager@chromium.org3811b432009-10-28 14:53:37 +00002557void* ExternalArray::external_pointer() {
2558 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2559 return reinterpret_cast<void*>(ptr);
2560}
2561
2562
2563void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2564 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2565 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2566}
2567
2568
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002569int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002570 ASSERT((index >= 0) && (index < this->length()));
2571 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2572 return ptr[index];
2573}
2574
2575
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002576MaybeObject* ExternalByteArray::get(int index) {
2577 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2578}
2579
2580
ager@chromium.org3811b432009-10-28 14:53:37 +00002581void ExternalByteArray::set(int index, int8_t value) {
2582 ASSERT((index >= 0) && (index < this->length()));
2583 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2584 ptr[index] = value;
2585}
2586
2587
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002588uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002589 ASSERT((index >= 0) && (index < this->length()));
2590 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2591 return ptr[index];
2592}
2593
2594
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002595MaybeObject* ExternalUnsignedByteArray::get(int index) {
2596 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2597}
2598
2599
ager@chromium.org3811b432009-10-28 14:53:37 +00002600void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2601 ASSERT((index >= 0) && (index < this->length()));
2602 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2603 ptr[index] = value;
2604}
2605
2606
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002607int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002608 ASSERT((index >= 0) && (index < this->length()));
2609 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2610 return ptr[index];
2611}
2612
2613
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002614MaybeObject* ExternalShortArray::get(int index) {
2615 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2616}
2617
2618
ager@chromium.org3811b432009-10-28 14:53:37 +00002619void ExternalShortArray::set(int index, int16_t value) {
2620 ASSERT((index >= 0) && (index < this->length()));
2621 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2622 ptr[index] = value;
2623}
2624
2625
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002626uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002627 ASSERT((index >= 0) && (index < this->length()));
2628 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2629 return ptr[index];
2630}
2631
2632
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002633MaybeObject* ExternalUnsignedShortArray::get(int index) {
2634 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2635}
2636
2637
ager@chromium.org3811b432009-10-28 14:53:37 +00002638void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2639 ASSERT((index >= 0) && (index < this->length()));
2640 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2641 ptr[index] = value;
2642}
2643
2644
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002645int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002646 ASSERT((index >= 0) && (index < this->length()));
2647 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2648 return ptr[index];
2649}
2650
2651
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002652MaybeObject* ExternalIntArray::get(int index) {
2653 return GetHeap()->NumberFromInt32(get_scalar(index));
2654}
2655
2656
ager@chromium.org3811b432009-10-28 14:53:37 +00002657void ExternalIntArray::set(int index, int32_t value) {
2658 ASSERT((index >= 0) && (index < this->length()));
2659 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2660 ptr[index] = value;
2661}
2662
2663
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002664uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002665 ASSERT((index >= 0) && (index < this->length()));
2666 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2667 return ptr[index];
2668}
2669
2670
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002671MaybeObject* ExternalUnsignedIntArray::get(int index) {
2672 return GetHeap()->NumberFromUint32(get_scalar(index));
2673}
2674
2675
ager@chromium.org3811b432009-10-28 14:53:37 +00002676void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2677 ASSERT((index >= 0) && (index < this->length()));
2678 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2679 ptr[index] = value;
2680}
2681
2682
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002683float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002684 ASSERT((index >= 0) && (index < this->length()));
2685 float* ptr = static_cast<float*>(external_pointer());
2686 return ptr[index];
2687}
2688
2689
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002690MaybeObject* ExternalFloatArray::get(int index) {
2691 return GetHeap()->NumberFromDouble(get_scalar(index));
2692}
2693
2694
ager@chromium.org3811b432009-10-28 14:53:37 +00002695void ExternalFloatArray::set(int index, float value) {
2696 ASSERT((index >= 0) && (index < this->length()));
2697 float* ptr = static_cast<float*>(external_pointer());
2698 ptr[index] = value;
2699}
2700
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002701
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002702double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002703 ASSERT((index >= 0) && (index < this->length()));
2704 double* ptr = static_cast<double*>(external_pointer());
2705 return ptr[index];
2706}
2707
2708
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002709MaybeObject* ExternalDoubleArray::get(int index) {
2710 return GetHeap()->NumberFromDouble(get_scalar(index));
2711}
2712
2713
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002714void ExternalDoubleArray::set(int index, double value) {
2715 ASSERT((index >= 0) && (index < this->length()));
2716 double* ptr = static_cast<double*>(external_pointer());
2717 ptr[index] = value;
2718}
2719
2720
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002721int Map::visitor_id() {
2722 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2723}
2724
2725
2726void Map::set_visitor_id(int id) {
2727 ASSERT(0 <= id && id < 256);
2728 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2729}
2730
ager@chromium.org3811b432009-10-28 14:53:37 +00002731
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002732int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002733 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2734}
2735
2736
2737int Map::inobject_properties() {
2738 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002739}
2740
2741
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002742int Map::pre_allocated_property_fields() {
2743 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2744}
2745
2746
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002747int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002748 int instance_size = map->instance_size();
2749 if (instance_size != kVariableSizeSentinel) return instance_size;
2750 // We can ignore the "symbol" bit becase it is only set for symbols
2751 // and implies a string type.
2752 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002753 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002754 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002755 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002756 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002757 if (instance_type == ASCII_STRING_TYPE) {
2758 return SeqAsciiString::SizeFor(
2759 reinterpret_cast<SeqAsciiString*>(this)->length());
2760 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002761 if (instance_type == BYTE_ARRAY_TYPE) {
2762 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2763 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002764 if (instance_type == FREE_SPACE_TYPE) {
2765 return reinterpret_cast<FreeSpace*>(this)->size();
2766 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002767 if (instance_type == STRING_TYPE) {
2768 return SeqTwoByteString::SizeFor(
2769 reinterpret_cast<SeqTwoByteString*>(this)->length());
2770 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002771 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2772 return FixedDoubleArray::SizeFor(
2773 reinterpret_cast<FixedDoubleArray*>(this)->length());
2774 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002775 ASSERT(instance_type == CODE_TYPE);
2776 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002777}
2778
2779
2780void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002781 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002782 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002783 ASSERT(0 <= value && value < 256);
2784 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2785}
2786
2787
ager@chromium.org7c537e22008-10-16 08:43:32 +00002788void Map::set_inobject_properties(int value) {
2789 ASSERT(0 <= value && value < 256);
2790 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2791}
2792
2793
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002794void Map::set_pre_allocated_property_fields(int value) {
2795 ASSERT(0 <= value && value < 256);
2796 WRITE_BYTE_FIELD(this,
2797 kPreAllocatedPropertyFieldsOffset,
2798 static_cast<byte>(value));
2799}
2800
2801
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002802InstanceType Map::instance_type() {
2803 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2804}
2805
2806
2807void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002808 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2809}
2810
2811
2812int Map::unused_property_fields() {
2813 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2814}
2815
2816
2817void Map::set_unused_property_fields(int value) {
2818 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2819}
2820
2821
2822byte Map::bit_field() {
2823 return READ_BYTE_FIELD(this, kBitFieldOffset);
2824}
2825
2826
2827void Map::set_bit_field(byte value) {
2828 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2829}
2830
2831
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002832byte Map::bit_field2() {
2833 return READ_BYTE_FIELD(this, kBitField2Offset);
2834}
2835
2836
2837void Map::set_bit_field2(byte value) {
2838 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2839}
2840
2841
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002842void Map::set_non_instance_prototype(bool value) {
2843 if (value) {
2844 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2845 } else {
2846 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2847 }
2848}
2849
2850
2851bool Map::has_non_instance_prototype() {
2852 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2853}
2854
2855
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002856void Map::set_function_with_prototype(bool value) {
2857 if (value) {
2858 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2859 } else {
2860 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2861 }
2862}
2863
2864
2865bool Map::function_with_prototype() {
2866 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2867}
2868
2869
ager@chromium.org870a0b62008-11-04 11:43:05 +00002870void Map::set_is_access_check_needed(bool access_check_needed) {
2871 if (access_check_needed) {
2872 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2873 } else {
2874 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2875 }
2876}
2877
2878
2879bool Map::is_access_check_needed() {
2880 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2881}
2882
2883
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002884void Map::set_is_extensible(bool value) {
2885 if (value) {
2886 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2887 } else {
2888 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2889 }
2890}
2891
2892bool Map::is_extensible() {
2893 return ((1 << kIsExtensible) & bit_field2()) != 0;
2894}
2895
2896
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002897void Map::set_attached_to_shared_function_info(bool value) {
2898 if (value) {
2899 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2900 } else {
2901 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2902 }
2903}
2904
2905bool Map::attached_to_shared_function_info() {
2906 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2907}
2908
2909
2910void Map::set_is_shared(bool value) {
2911 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002912 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002913 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002914 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002915 }
2916}
2917
2918bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002919 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002920}
2921
2922
2923JSFunction* Map::unchecked_constructor() {
2924 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2925}
2926
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002927
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002928Code::Flags Code::flags() {
2929 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2930}
2931
2932
2933void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002934 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002935 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002936 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2937 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002938 ExtractArgumentsCountFromFlags(flags) >= 0);
2939 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2940}
2941
2942
2943Code::Kind Code::kind() {
2944 return ExtractKindFromFlags(flags());
2945}
2946
2947
kasper.lund7276f142008-07-30 08:49:36 +00002948InlineCacheState Code::ic_state() {
2949 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002950 // Only allow uninitialized or debugger states for non-IC code
2951 // objects. This is used in the debugger to determine whether or not
2952 // a call to code object has been replaced with a debug break call.
2953 ASSERT(is_inline_cache_stub() ||
2954 result == UNINITIALIZED ||
2955 result == DEBUG_BREAK ||
2956 result == DEBUG_PREPARE_STEP_IN);
2957 return result;
2958}
2959
2960
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002961Code::ExtraICState Code::extra_ic_state() {
2962 ASSERT(is_inline_cache_stub());
2963 return ExtractExtraICStateFromFlags(flags());
2964}
2965
2966
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002967PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002968 return ExtractTypeFromFlags(flags());
2969}
2970
2971
2972int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002973 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002974 return ExtractArgumentsCountFromFlags(flags());
2975}
2976
2977
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002978int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002979 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002980 kind() == UNARY_OP_IC ||
2981 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002982 kind() == COMPARE_IC ||
2983 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002984 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002985}
2986
2987
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002988void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002989 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002990 kind() == UNARY_OP_IC ||
2991 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002992 kind() == COMPARE_IC ||
2993 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002994 ASSERT(0 <= major && major < 256);
2995 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002996}
2997
2998
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002999bool Code::is_pregenerated() {
3000 return kind() == STUB && IsPregeneratedField::decode(flags());
3001}
3002
3003
3004void Code::set_is_pregenerated(bool value) {
3005 ASSERT(kind() == STUB);
3006 Flags f = flags();
3007 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3008 set_flags(f);
3009}
3010
3011
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003012bool Code::optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003013 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003014 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3015}
3016
3017
3018void Code::set_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003019 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003020 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3021}
3022
3023
3024bool Code::has_deoptimization_support() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003025 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003026 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3027 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003028}
3029
3030
3031void Code::set_has_deoptimization_support(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003032 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003033 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3034 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3035 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3036}
3037
3038
3039bool Code::has_debug_break_slots() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003040 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003041 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3042 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3043}
3044
3045
3046void Code::set_has_debug_break_slots(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003047 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003048 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3049 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3050 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003051}
3052
3053
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003054bool Code::is_compiled_optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003055 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003056 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3057 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3058}
3059
3060
3061void Code::set_compiled_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003062 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003063 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3064 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3065 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3066}
3067
3068
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003069int Code::allow_osr_at_loop_nesting_level() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003070 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003071 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3072}
3073
3074
3075void Code::set_allow_osr_at_loop_nesting_level(int level) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003076 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003077 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3078 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3079}
3080
3081
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003082int Code::profiler_ticks() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003083 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003084 return READ_BYTE_FIELD(this, kProfilerTicksOffset);
3085}
3086
3087
3088void Code::set_profiler_ticks(int ticks) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003089 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003090 ASSERT(ticks < 256);
3091 WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
3092}
3093
3094
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003095unsigned Code::stack_slots() {
3096 ASSERT(kind() == OPTIMIZED_FUNCTION);
3097 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3098}
3099
3100
3101void Code::set_stack_slots(unsigned slots) {
3102 ASSERT(kind() == OPTIMIZED_FUNCTION);
3103 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3104}
3105
3106
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003107unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003108 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003109 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003110}
3111
3112
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003113void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003114 ASSERT(kind() == OPTIMIZED_FUNCTION);
3115 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003116 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003117}
3118
3119
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003120unsigned Code::stack_check_table_offset() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003121 ASSERT_EQ(FUNCTION, kind());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003122 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003123}
3124
3125
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003126void Code::set_stack_check_table_offset(unsigned offset) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003127 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003128 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003129 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003130}
3131
3132
3133CheckType Code::check_type() {
3134 ASSERT(is_call_stub() || is_keyed_call_stub());
3135 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3136 return static_cast<CheckType>(type);
3137}
3138
3139
3140void Code::set_check_type(CheckType value) {
3141 ASSERT(is_call_stub() || is_keyed_call_stub());
3142 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3143}
3144
3145
danno@chromium.org40cb8782011-05-25 07:58:50 +00003146byte Code::unary_op_type() {
3147 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003148 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3149}
3150
3151
danno@chromium.org40cb8782011-05-25 07:58:50 +00003152void Code::set_unary_op_type(byte value) {
3153 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003154 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3155}
3156
3157
danno@chromium.org40cb8782011-05-25 07:58:50 +00003158byte Code::binary_op_type() {
3159 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003160 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3161}
3162
3163
danno@chromium.org40cb8782011-05-25 07:58:50 +00003164void Code::set_binary_op_type(byte value) {
3165 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003166 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3167}
3168
3169
danno@chromium.org40cb8782011-05-25 07:58:50 +00003170byte Code::binary_op_result_type() {
3171 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003172 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3173}
3174
3175
danno@chromium.org40cb8782011-05-25 07:58:50 +00003176void Code::set_binary_op_result_type(byte value) {
3177 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003178 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3179}
3180
3181
3182byte Code::compare_state() {
3183 ASSERT(is_compare_ic_stub());
3184 return READ_BYTE_FIELD(this, kCompareStateOffset);
3185}
3186
3187
3188void Code::set_compare_state(byte value) {
3189 ASSERT(is_compare_ic_stub());
3190 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3191}
3192
3193
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003194byte Code::to_boolean_state() {
3195 ASSERT(is_to_boolean_ic_stub());
3196 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3197}
3198
3199
3200void Code::set_to_boolean_state(byte value) {
3201 ASSERT(is_to_boolean_ic_stub());
3202 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3203}
3204
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003205
3206bool Code::has_function_cache() {
3207 ASSERT(kind() == STUB);
3208 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3209}
3210
3211
3212void Code::set_has_function_cache(bool flag) {
3213 ASSERT(kind() == STUB);
3214 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3215}
3216
3217
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003218bool Code::is_inline_cache_stub() {
3219 Kind kind = this->kind();
3220 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3221}
3222
3223
3224Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003225 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003226 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003227 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003228 int argc,
3229 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003230 // Extra IC state is only allowed for call IC stubs or for store IC
3231 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003232 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003233 kind == CALL_IC ||
3234 kind == STORE_IC ||
3235 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003236 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003237 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003238 | ICStateField::encode(ic_state)
3239 | TypeField::encode(type)
3240 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003241 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003242 | CacheHolderField::encode(holder);
3243 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003244}
3245
3246
3247Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3248 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003249 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003250 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003251 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003252 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003253}
3254
3255
3256Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003257 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003258}
3259
3260
kasper.lund7276f142008-07-30 08:49:36 +00003261InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003262 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003263}
3264
3265
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003266Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003267 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003268}
3269
3270
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003271PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003272 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003273}
3274
3275
3276int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003277 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003278}
3279
3280
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003281InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003282 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003283}
3284
3285
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003286Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003287 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003288 return static_cast<Flags>(bits);
3289}
3290
3291
ager@chromium.org8bb60582008-12-11 12:02:20 +00003292Code* Code::GetCodeFromTargetAddress(Address address) {
3293 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3294 // GetCodeFromTargetAddress might be called when marking objects during mark
3295 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3296 // Code::cast. Code::cast does not work when the object's map is
3297 // marked.
3298 Code* result = reinterpret_cast<Code*>(code);
3299 return result;
3300}
3301
3302
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003303Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3304 return HeapObject::
3305 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3306}
3307
3308
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003309Object* Map::prototype() {
3310 return READ_FIELD(this, kPrototypeOffset);
3311}
3312
3313
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003314void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003315 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003316 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003317 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003318}
3319
3320
danno@chromium.org40cb8782011-05-25 07:58:50 +00003321DescriptorArray* Map::instance_descriptors() {
3322 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3323 if (object->IsSmi()) {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003324 return GetHeap()->empty_descriptor_array();
danno@chromium.org40cb8782011-05-25 07:58:50 +00003325 } else {
3326 return DescriptorArray::cast(object);
3327 }
3328}
3329
3330
3331void Map::init_instance_descriptors() {
3332 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3333}
3334
3335
3336void Map::clear_instance_descriptors() {
3337 Object* object = READ_FIELD(this,
3338 kInstanceDescriptorsOrBitField3Offset);
3339 if (!object->IsSmi()) {
3340 WRITE_FIELD(
3341 this,
3342 kInstanceDescriptorsOrBitField3Offset,
3343 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3344 }
3345}
3346
3347
3348void Map::set_instance_descriptors(DescriptorArray* value,
3349 WriteBarrierMode mode) {
3350 Object* object = READ_FIELD(this,
3351 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003352 Heap* heap = GetHeap();
3353 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003354 clear_instance_descriptors();
3355 return;
3356 } else {
3357 if (object->IsSmi()) {
3358 value->set_bit_field3_storage(Smi::cast(object)->value());
3359 } else {
3360 value->set_bit_field3_storage(
3361 DescriptorArray::cast(object)->bit_field3_storage());
3362 }
3363 }
3364 ASSERT(!is_shared());
3365 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003366 CONDITIONAL_WRITE_BARRIER(
3367 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003368}
3369
3370
3371int Map::bit_field3() {
3372 Object* object = READ_FIELD(this,
3373 kInstanceDescriptorsOrBitField3Offset);
3374 if (object->IsSmi()) {
3375 return Smi::cast(object)->value();
3376 } else {
3377 return DescriptorArray::cast(object)->bit_field3_storage();
3378 }
3379}
3380
3381
3382void Map::set_bit_field3(int value) {
3383 ASSERT(Smi::IsValid(value));
3384 Object* object = READ_FIELD(this,
3385 kInstanceDescriptorsOrBitField3Offset);
3386 if (object->IsSmi()) {
3387 WRITE_FIELD(this,
3388 kInstanceDescriptorsOrBitField3Offset,
3389 Smi::FromInt(value));
3390 } else {
3391 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3392 }
3393}
3394
3395
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003396FixedArray* Map::unchecked_prototype_transitions() {
3397 return reinterpret_cast<FixedArray*>(
3398 READ_FIELD(this, kPrototypeTransitionsOffset));
3399}
3400
3401
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003402ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003403ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003404ACCESSORS(Map, constructor, Object, kConstructorOffset)
3405
3406ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003407ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003408ACCESSORS(JSFunction,
3409 next_function_link,
3410 Object,
3411 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003412
3413ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3414ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003415ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003416
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003417ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003418
3419ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3420ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3421ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3422ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003423ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003424
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003425ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3426ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3427
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003428ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3429ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3430ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3431
3432ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3433ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3434ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3435ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3436ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3437ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3438
3439ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3440ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3441
3442ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3443ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3444
3445ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3446ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003447ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3448 kPropertyAccessorsOffset)
3449ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3450 kPrototypeTemplateOffset)
3451ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3452ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3453 kNamedPropertyHandlerOffset)
3454ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3455 kIndexedPropertyHandlerOffset)
3456ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3457 kInstanceTemplateOffset)
3458ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3459ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003460ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3461 kInstanceCallHandlerOffset)
3462ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3463 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003464ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003465
3466ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003467ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3468 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003469
3470ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3471ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3472
3473ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3474
3475ACCESSORS(Script, source, Object, kSourceOffset)
3476ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003477ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003478ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
3479ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003480ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003481ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003482ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003483ACCESSORS_TO_SMI(Script, type, kTypeOffset)
3484ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
3485ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003486ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003487ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003488ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
3489 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003490
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003491#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003492ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3493ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3494ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3495ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3496
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003497ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
3498ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
3499ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003500ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003501#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003502
3503ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003504ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3505ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003506ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3507 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003508ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003509ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3510ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003511ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003512ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3513 kThisPropertyAssignmentsOffset)
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003514SMI_ACCESSORS(SharedFunctionInfo, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003515
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00003516
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003517BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3518 kHiddenPrototypeBit)
3519BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3520BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3521 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003522BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3523 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003524BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3525 kIsExpressionBit)
3526BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3527 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003528BOOL_GETTER(SharedFunctionInfo,
3529 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003530 has_only_simple_this_property_assignments,
3531 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003532BOOL_ACCESSORS(SharedFunctionInfo,
3533 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003534 allows_lazy_compilation,
3535 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003536BOOL_ACCESSORS(SharedFunctionInfo,
3537 compiler_hints,
3538 uses_arguments,
3539 kUsesArguments)
3540BOOL_ACCESSORS(SharedFunctionInfo,
3541 compiler_hints,
3542 has_duplicate_parameters,
3543 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003544
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003545
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003546#if V8_HOST_ARCH_32_BIT
3547SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3548SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003549 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003550SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003551 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003552SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3553SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003554 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003555SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3556SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003557 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003558SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003559 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003560SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003561 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003562SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003563SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3564SMI_ACCESSORS(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003565#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003566
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003567#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003568 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003569 int holder::name() { \
3570 int value = READ_INT_FIELD(this, offset); \
3571 ASSERT(kHeapObjectTag == 1); \
3572 ASSERT((value & kHeapObjectTag) == 0); \
3573 return value >> 1; \
3574 } \
3575 void holder::set_##name(int value) { \
3576 ASSERT(kHeapObjectTag == 1); \
3577 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3578 (value & 0xC0000000) == 0x000000000); \
3579 WRITE_INT_FIELD(this, \
3580 offset, \
3581 (value << 1) & ~kHeapObjectTag); \
3582 }
3583
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003584#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3585 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003586 INT_ACCESSORS(holder, name, offset)
3587
3588
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003589PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003590PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3591 formal_parameter_count,
3592 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003593
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003594PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3595 expected_nof_properties,
3596 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003597PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3598
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003599PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3600PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3601 start_position_and_type,
3602 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003603
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003604PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3605 function_token_position,
3606 kFunctionTokenPositionOffset)
3607PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3608 compiler_hints,
3609 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003610
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003611PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3612 this_property_assignments_count,
3613 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003614PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003615
3616PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3617PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003618#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003619
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003620
3621int SharedFunctionInfo::construction_count() {
3622 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3623}
3624
3625
3626void SharedFunctionInfo::set_construction_count(int value) {
3627 ASSERT(0 <= value && value < 256);
3628 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3629}
3630
3631
whesse@chromium.org7b260152011-06-20 15:33:18 +00003632BOOL_ACCESSORS(SharedFunctionInfo,
3633 compiler_hints,
3634 live_objects_may_exist,
3635 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003636
3637
3638bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003639 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003640}
3641
3642
whesse@chromium.org7b260152011-06-20 15:33:18 +00003643BOOL_GETTER(SharedFunctionInfo,
3644 compiler_hints,
3645 optimization_disabled,
3646 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003647
3648
3649void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3650 set_compiler_hints(BooleanBit::set(compiler_hints(),
3651 kOptimizationDisabled,
3652 disable));
3653 // If disabling optimizations we reflect that in the code object so
3654 // it will not be counted as optimizable code.
3655 if ((code()->kind() == Code::FUNCTION) && disable) {
3656 code()->set_optimizable(false);
3657 }
3658}
3659
3660
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003661LanguageMode SharedFunctionInfo::language_mode() {
3662 int hints = compiler_hints();
3663 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3664 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3665 return EXTENDED_MODE;
3666 }
3667 return BooleanBit::get(hints, kStrictModeFunction)
3668 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003669}
3670
3671
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003672void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3673 // We only allow language mode transitions that go set the same language mode
3674 // again or go up in the chain:
3675 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3676 ASSERT(this->language_mode() == CLASSIC_MODE ||
3677 this->language_mode() == language_mode ||
3678 language_mode == EXTENDED_MODE);
3679 int hints = compiler_hints();
3680 hints = BooleanBit::set(
3681 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3682 hints = BooleanBit::set(
3683 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3684 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003685}
3686
3687
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003688bool SharedFunctionInfo::is_classic_mode() {
3689 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3690}
3691
3692BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3693 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003694BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3695BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3696 name_should_print_as_anonymous,
3697 kNameShouldPrintAsAnonymous)
3698BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3699BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00003700BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
3701BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
3702 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003703BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003704
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003705ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3706ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3707
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003708ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3709
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003710bool Script::HasValidSource() {
3711 Object* src = this->source();
3712 if (!src->IsString()) return true;
3713 String* src_str = String::cast(src);
3714 if (!StringShape(src_str).IsExternal()) return true;
3715 if (src_str->IsAsciiRepresentation()) {
3716 return ExternalAsciiString::cast(src)->resource() != NULL;
3717 } else if (src_str->IsTwoByteRepresentation()) {
3718 return ExternalTwoByteString::cast(src)->resource() != NULL;
3719 }
3720 return true;
3721}
3722
3723
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003724void SharedFunctionInfo::DontAdaptArguments() {
3725 ASSERT(code()->kind() == Code::BUILTIN);
3726 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3727}
3728
3729
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003730int SharedFunctionInfo::start_position() {
3731 return start_position_and_type() >> kStartPositionShift;
3732}
3733
3734
3735void SharedFunctionInfo::set_start_position(int start_position) {
3736 set_start_position_and_type((start_position << kStartPositionShift)
3737 | (start_position_and_type() & ~kStartPositionMask));
3738}
3739
3740
3741Code* SharedFunctionInfo::code() {
3742 return Code::cast(READ_FIELD(this, kCodeOffset));
3743}
3744
3745
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003746Code* SharedFunctionInfo::unchecked_code() {
3747 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3748}
3749
3750
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003751void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003752 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003753 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003754}
3755
3756
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003757ScopeInfo* SharedFunctionInfo::scope_info() {
3758 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003759}
3760
3761
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003762void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003763 WriteBarrierMode mode) {
3764 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003765 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3766 this,
3767 kScopeInfoOffset,
3768 reinterpret_cast<Object*>(value),
3769 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003770}
3771
3772
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003773bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003774 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003775 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003776}
3777
3778
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003779bool SharedFunctionInfo::IsApiFunction() {
3780 return function_data()->IsFunctionTemplateInfo();
3781}
3782
3783
3784FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3785 ASSERT(IsApiFunction());
3786 return FunctionTemplateInfo::cast(function_data());
3787}
3788
3789
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003790bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003791 return function_data()->IsSmi();
3792}
3793
3794
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003795BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3796 ASSERT(HasBuiltinFunctionId());
3797 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003798}
3799
3800
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003801int SharedFunctionInfo::code_age() {
3802 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3803}
3804
3805
3806void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00003807 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3808 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003809}
3810
3811
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003812bool SharedFunctionInfo::has_deoptimization_support() {
3813 Code* code = this->code();
3814 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3815}
3816
3817
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003818bool JSFunction::IsBuiltin() {
3819 return context()->global()->IsJSBuiltinsObject();
3820}
3821
3822
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003823bool JSFunction::NeedsArgumentsAdaption() {
3824 return shared()->formal_parameter_count() !=
3825 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3826}
3827
3828
3829bool JSFunction::IsOptimized() {
3830 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3831}
3832
3833
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003834bool JSFunction::IsOptimizable() {
3835 return code()->kind() == Code::FUNCTION && code()->optimizable();
3836}
3837
3838
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003839bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003840 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003841}
3842
3843
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003844Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003845 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003846}
3847
3848
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003849Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003850 return reinterpret_cast<Code*>(
3851 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003852}
3853
3854
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003855void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003856 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003857 Address entry = value->entry();
3858 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003859 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3860 this,
3861 HeapObject::RawField(this, kCodeEntryOffset),
3862 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003863}
3864
3865
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003866void JSFunction::ReplaceCode(Code* code) {
3867 bool was_optimized = IsOptimized();
3868 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3869
3870 set_code(code);
3871
3872 // Add/remove the function from the list of optimized functions for this
3873 // context based on the state change.
3874 if (!was_optimized && is_optimized) {
3875 context()->global_context()->AddOptimizedFunction(this);
3876 }
3877 if (was_optimized && !is_optimized) {
3878 context()->global_context()->RemoveOptimizedFunction(this);
3879 }
3880}
3881
3882
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003883Context* JSFunction::context() {
3884 return Context::cast(READ_FIELD(this, kContextOffset));
3885}
3886
3887
3888Object* JSFunction::unchecked_context() {
3889 return READ_FIELD(this, kContextOffset);
3890}
3891
3892
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003893SharedFunctionInfo* JSFunction::unchecked_shared() {
3894 return reinterpret_cast<SharedFunctionInfo*>(
3895 READ_FIELD(this, kSharedFunctionInfoOffset));
3896}
3897
3898
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003899void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003900 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003901 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003902 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003903}
3904
3905ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3906 kPrototypeOrInitialMapOffset)
3907
3908
3909Map* JSFunction::initial_map() {
3910 return Map::cast(prototype_or_initial_map());
3911}
3912
3913
3914void JSFunction::set_initial_map(Map* value) {
3915 set_prototype_or_initial_map(value);
3916}
3917
3918
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003919MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
3920 Map* initial_map) {
3921 Context* global_context = context()->global_context();
3922 Object* array_function =
3923 global_context->get(Context::ARRAY_FUNCTION_INDEX);
3924 if (array_function->IsJSFunction() &&
3925 this == JSFunction::cast(array_function)) {
3926 ASSERT(initial_map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
3927
3928 MaybeObject* maybe_map = initial_map->CopyDropTransitions();
3929 Map* new_double_map = NULL;
3930 if (!maybe_map->To<Map>(&new_double_map)) return maybe_map;
3931 new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00003932 maybe_map = initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS,
3933 new_double_map);
3934 if (maybe_map->IsFailure()) return maybe_map;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003935
3936 maybe_map = new_double_map->CopyDropTransitions();
3937 Map* new_object_map = NULL;
3938 if (!maybe_map->To<Map>(&new_object_map)) return maybe_map;
3939 new_object_map->set_elements_kind(FAST_ELEMENTS);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00003940 maybe_map = new_double_map->AddElementsTransition(FAST_ELEMENTS,
3941 new_object_map);
3942 if (maybe_map->IsFailure()) return maybe_map;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003943
3944 global_context->set_smi_js_array_map(initial_map);
3945 global_context->set_double_js_array_map(new_double_map);
3946 global_context->set_object_js_array_map(new_object_map);
3947 }
3948 set_initial_map(initial_map);
3949 return this;
3950}
3951
3952
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003953bool JSFunction::has_initial_map() {
3954 return prototype_or_initial_map()->IsMap();
3955}
3956
3957
3958bool JSFunction::has_instance_prototype() {
3959 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3960}
3961
3962
3963bool JSFunction::has_prototype() {
3964 return map()->has_non_instance_prototype() || has_instance_prototype();
3965}
3966
3967
3968Object* JSFunction::instance_prototype() {
3969 ASSERT(has_instance_prototype());
3970 if (has_initial_map()) return initial_map()->prototype();
3971 // When there is no initial map and the prototype is a JSObject, the
3972 // initial map field is used for the prototype field.
3973 return prototype_or_initial_map();
3974}
3975
3976
3977Object* JSFunction::prototype() {
3978 ASSERT(has_prototype());
3979 // If the function's prototype property has been set to a non-JSObject
3980 // value, that value is stored in the constructor field of the map.
3981 if (map()->has_non_instance_prototype()) return map()->constructor();
3982 return instance_prototype();
3983}
3984
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003985bool JSFunction::should_have_prototype() {
3986 return map()->function_with_prototype();
3987}
3988
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003989
3990bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003991 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003992}
3993
3994
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003995FixedArray* JSFunction::literals() {
3996 ASSERT(!shared()->bound());
3997 return literals_or_bindings();
3998}
3999
4000
4001void JSFunction::set_literals(FixedArray* literals) {
4002 ASSERT(!shared()->bound());
4003 set_literals_or_bindings(literals);
4004}
4005
4006
4007FixedArray* JSFunction::function_bindings() {
4008 ASSERT(shared()->bound());
4009 return literals_or_bindings();
4010}
4011
4012
4013void JSFunction::set_function_bindings(FixedArray* bindings) {
4014 ASSERT(shared()->bound());
4015 // Bound function literal may be initialized to the empty fixed array
4016 // before the bindings are set.
4017 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4018 bindings->map() == GetHeap()->fixed_cow_array_map());
4019 set_literals_or_bindings(bindings);
4020}
4021
4022
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004023int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004024 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004025 return literals()->length();
4026}
4027
4028
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004029Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004030 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004031 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004032}
4033
4034
4035void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4036 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004037 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004038 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004039 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004040}
4041
4042
4043Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004044 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004045 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4046}
4047
4048
4049void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4050 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004051 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004052 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004053 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004054}
4055
4056
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004057ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004058ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004059ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4060ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4061
4062
4063void JSProxy::InitializeBody(int object_size, Object* value) {
4064 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4065 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4066 WRITE_FIELD(this, offset, value);
4067 }
4068}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004069
4070
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004071ACCESSORS(JSSet, table, Object, kTableOffset)
4072ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004073ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4074ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004075
4076
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004077Address Foreign::foreign_address() {
4078 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004079}
4080
4081
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004082void Foreign::set_foreign_address(Address value) {
4083 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004084}
4085
4086
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004087ACCESSORS(JSModule, context, Object, kContextOffset)
4088
4089
4090JSModule* JSModule::cast(Object* obj) {
4091 ASSERT(obj->IsJSModule());
4092 ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
4093 return reinterpret_cast<JSModule*>(obj);
4094}
4095
4096
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004097ACCESSORS(JSValue, value, Object, kValueOffset)
4098
4099
4100JSValue* JSValue::cast(Object* obj) {
4101 ASSERT(obj->IsJSValue());
4102 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4103 return reinterpret_cast<JSValue*>(obj);
4104}
4105
4106
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004107ACCESSORS(JSDate, value, Object, kValueOffset)
4108ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4109ACCESSORS(JSDate, year, Object, kYearOffset)
4110ACCESSORS(JSDate, month, Object, kMonthOffset)
4111ACCESSORS(JSDate, day, Object, kDayOffset)
4112ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4113ACCESSORS(JSDate, hour, Object, kHourOffset)
4114ACCESSORS(JSDate, min, Object, kMinOffset)
4115ACCESSORS(JSDate, sec, Object, kSecOffset)
4116
4117
4118JSDate* JSDate::cast(Object* obj) {
4119 ASSERT(obj->IsJSDate());
4120 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4121 return reinterpret_cast<JSDate*>(obj);
4122}
4123
4124
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004125ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4126ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4127ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4128ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4129ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4130SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4131SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4132
4133
4134JSMessageObject* JSMessageObject::cast(Object* obj) {
4135 ASSERT(obj->IsJSMessageObject());
4136 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4137 return reinterpret_cast<JSMessageObject*>(obj);
4138}
4139
4140
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004141INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004142ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004143ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004144ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004145ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004146ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00004147INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004148
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004149byte* Code::instruction_start() {
4150 return FIELD_ADDR(this, kHeaderSize);
4151}
4152
4153
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004154byte* Code::instruction_end() {
4155 return instruction_start() + instruction_size();
4156}
4157
4158
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004159int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004160 return RoundUp(instruction_size(), kObjectAlignment);
4161}
4162
4163
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004164FixedArray* Code::unchecked_deoptimization_data() {
4165 return reinterpret_cast<FixedArray*>(
4166 READ_FIELD(this, kDeoptimizationDataOffset));
4167}
4168
4169
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004170ByteArray* Code::unchecked_relocation_info() {
4171 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004172}
4173
4174
4175byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004176 return unchecked_relocation_info()->GetDataStartAddress();
4177}
4178
4179
4180int Code::relocation_size() {
4181 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004182}
4183
4184
4185byte* Code::entry() {
4186 return instruction_start();
4187}
4188
4189
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004190bool Code::contains(byte* inner_pointer) {
4191 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004192}
4193
4194
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004195ACCESSORS(JSArray, length, Object, kLengthOffset)
4196
4197
ager@chromium.org236ad962008-09-25 09:45:57 +00004198ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004199
4200
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004201JSRegExp::Type JSRegExp::TypeTag() {
4202 Object* data = this->data();
4203 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4204 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4205 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004206}
4207
4208
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004209JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4210 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4211 return static_cast<JSRegExp::Type>(smi->value());
4212}
4213
4214
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004215int JSRegExp::CaptureCount() {
4216 switch (TypeTag()) {
4217 case ATOM:
4218 return 0;
4219 case IRREGEXP:
4220 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4221 default:
4222 UNREACHABLE();
4223 return -1;
4224 }
4225}
4226
4227
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004228JSRegExp::Flags JSRegExp::GetFlags() {
4229 ASSERT(this->data()->IsFixedArray());
4230 Object* data = this->data();
4231 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4232 return Flags(smi->value());
4233}
4234
4235
4236String* JSRegExp::Pattern() {
4237 ASSERT(this->data()->IsFixedArray());
4238 Object* data = this->data();
4239 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4240 return pattern;
4241}
4242
4243
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004244Object* JSRegExp::DataAt(int index) {
4245 ASSERT(TypeTag() != NOT_COMPILED);
4246 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004247}
4248
4249
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004250Object* JSRegExp::DataAtUnchecked(int index) {
4251 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4252 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4253 return READ_FIELD(fa, offset);
4254}
4255
4256
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004257void JSRegExp::SetDataAt(int index, Object* value) {
4258 ASSERT(TypeTag() != NOT_COMPILED);
4259 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4260 FixedArray::cast(data())->set(index, value);
4261}
4262
4263
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004264void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4265 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4266 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4267 if (value->IsSmi()) {
4268 fa->set_unchecked(index, Smi::cast(value));
4269 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004270 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004271 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4272 }
4273}
4274
4275
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004276ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004277 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004278#if DEBUG
4279 FixedArrayBase* fixed_array =
4280 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4281 Map* map = fixed_array->map();
4282 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004283 (map == GetHeap()->fixed_array_map() ||
4284 map == GetHeap()->fixed_cow_array_map())) ||
4285 (kind == FAST_DOUBLE_ELEMENTS &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004286 (fixed_array->IsFixedDoubleArray() ||
4287 fixed_array == GetHeap()->empty_fixed_array())) ||
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004288 (kind == DICTIONARY_ELEMENTS &&
4289 fixed_array->IsFixedArray() &&
4290 fixed_array->IsDictionary()) ||
4291 (kind > DICTIONARY_ELEMENTS));
4292 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4293 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004294#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004295 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004296}
4297
4298
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004299ElementsAccessor* JSObject::GetElementsAccessor() {
4300 return ElementsAccessor::ForKind(GetElementsKind());
4301}
4302
4303
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004304bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004305 return GetElementsKind() == FAST_ELEMENTS;
4306}
4307
4308
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004309bool JSObject::HasFastSmiOnlyElements() {
4310 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4311}
4312
4313
4314bool JSObject::HasFastTypeElements() {
4315 ElementsKind elements_kind = GetElementsKind();
4316 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4317 elements_kind == FAST_ELEMENTS;
4318}
4319
4320
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004321bool JSObject::HasFastDoubleElements() {
4322 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4323}
4324
4325
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004326bool JSObject::HasDictionaryElements() {
4327 return GetElementsKind() == DICTIONARY_ELEMENTS;
4328}
4329
4330
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004331bool JSObject::HasNonStrictArgumentsElements() {
4332 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4333}
4334
4335
ager@chromium.org3811b432009-10-28 14:53:37 +00004336bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004337 HeapObject* array = elements();
4338 ASSERT(array != NULL);
4339 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004340}
4341
4342
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004343#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4344bool JSObject::HasExternal##name##Elements() { \
4345 HeapObject* array = elements(); \
4346 ASSERT(array != NULL); \
4347 if (!array->IsHeapObject()) \
4348 return false; \
4349 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004350}
4351
4352
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004353EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4354EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4355EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4356EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4357 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4358EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4359EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4360 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4361EXTERNAL_ELEMENTS_CHECK(Float,
4362 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004363EXTERNAL_ELEMENTS_CHECK(Double,
4364 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004365EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004366
4367
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004368bool JSObject::HasNamedInterceptor() {
4369 return map()->has_named_interceptor();
4370}
4371
4372
4373bool JSObject::HasIndexedInterceptor() {
4374 return map()->has_indexed_interceptor();
4375}
4376
4377
lrn@chromium.org303ada72010-10-27 09:33:13 +00004378MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004379 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004380 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004381 Isolate* isolate = GetIsolate();
4382 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004383 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004384 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4385 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004386 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4387 return maybe_writable_elems;
4388 }
4389 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004390 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004391 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004392 return writable_elems;
4393}
4394
4395
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004396StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004397 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004398 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004399}
4400
4401
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004402SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004403 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004404 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004405}
4406
4407
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004408bool String::IsHashFieldComputed(uint32_t field) {
4409 return (field & kHashNotComputedMask) == 0;
4410}
4411
4412
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004413bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004414 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004415}
4416
4417
4418uint32_t String::Hash() {
4419 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004420 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004421 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004422 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004423 return ComputeAndSetHash();
4424}
4425
4426
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004427StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004428 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004429 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004430 array_index_(0),
4431 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4432 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004433 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004434 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004435}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004436
4437
4438bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004439 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004440}
4441
4442
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004443void StringHasher::AddCharacter(uint32_t c) {
4444 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4445 AddSurrogatePair(c); // Not inlined.
4446 return;
4447 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004448 // Use the Jenkins one-at-a-time hash function to update the hash
4449 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004450 raw_running_hash_ += c;
4451 raw_running_hash_ += (raw_running_hash_ << 10);
4452 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004453 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004454 if (is_array_index_) {
4455 if (c < '0' || c > '9') {
4456 is_array_index_ = false;
4457 } else {
4458 int d = c - '0';
4459 if (is_first_char_) {
4460 is_first_char_ = false;
4461 if (c == '0' && length_ > 1) {
4462 is_array_index_ = false;
4463 return;
4464 }
4465 }
4466 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4467 is_array_index_ = false;
4468 } else {
4469 array_index_ = array_index_ * 10 + d;
4470 }
4471 }
4472 }
4473}
4474
4475
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004476void StringHasher::AddCharacterNoIndex(uint32_t c) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00004477 ASSERT(!is_array_index());
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004478 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4479 AddSurrogatePairNoIndex(c); // Not inlined.
4480 return;
4481 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004482 raw_running_hash_ += c;
4483 raw_running_hash_ += (raw_running_hash_ << 10);
4484 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4485}
4486
4487
4488uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004489 // Get the calculated raw hash value and do some more bit ops to distribute
4490 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004491 uint32_t result = raw_running_hash_;
4492 result += (result << 3);
4493 result ^= (result >> 11);
4494 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004495 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004496 result = 27;
4497 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004498 return result;
4499}
4500
4501
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004502template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004503uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4504 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004505 if (!hasher.has_trivial_hash()) {
4506 int i;
4507 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4508 hasher.AddCharacter(chars[i]);
4509 }
4510 for (; i < length; i++) {
4511 hasher.AddCharacterNoIndex(chars[i]);
4512 }
4513 }
4514 return hasher.GetHashField();
4515}
4516
4517
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004518bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004519 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004520 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4521 return false;
4522 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004523 return SlowAsArrayIndex(index);
4524}
4525
4526
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004527Object* JSReceiver::GetPrototype() {
4528 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004529}
4530
4531
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004532bool JSReceiver::HasProperty(String* name) {
4533 if (IsJSProxy()) {
4534 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4535 }
4536 return GetPropertyAttribute(name) != ABSENT;
4537}
4538
4539
4540bool JSReceiver::HasLocalProperty(String* name) {
4541 if (IsJSProxy()) {
4542 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4543 }
4544 return GetLocalPropertyAttribute(name) != ABSENT;
4545}
4546
4547
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004548PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004549 return GetPropertyAttributeWithReceiver(this, key);
4550}
4551
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004552// TODO(504): this may be useful in other places too where JSGlobalProxy
4553// is used.
4554Object* JSObject::BypassGlobalProxy() {
4555 if (IsJSGlobalProxy()) {
4556 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004557 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004558 ASSERT(proto->IsJSGlobalObject());
4559 return proto;
4560 }
4561 return this;
4562}
4563
4564
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004565MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4566 return IsJSProxy()
4567 ? JSProxy::cast(this)->GetIdentityHash(flag)
4568 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004569}
4570
4571
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004572bool JSReceiver::HasElement(uint32_t index) {
4573 if (IsJSProxy()) {
4574 return JSProxy::cast(this)->HasElementWithHandler(index);
4575 }
4576 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004577}
4578
4579
4580bool AccessorInfo::all_can_read() {
4581 return BooleanBit::get(flag(), kAllCanReadBit);
4582}
4583
4584
4585void AccessorInfo::set_all_can_read(bool value) {
4586 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4587}
4588
4589
4590bool AccessorInfo::all_can_write() {
4591 return BooleanBit::get(flag(), kAllCanWriteBit);
4592}
4593
4594
4595void AccessorInfo::set_all_can_write(bool value) {
4596 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4597}
4598
4599
ager@chromium.org870a0b62008-11-04 11:43:05 +00004600bool AccessorInfo::prohibits_overwriting() {
4601 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4602}
4603
4604
4605void AccessorInfo::set_prohibits_overwriting(bool value) {
4606 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4607}
4608
4609
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004610PropertyAttributes AccessorInfo::property_attributes() {
4611 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4612}
4613
4614
4615void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004616 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004617}
4618
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004619
4620template<typename Shape, typename Key>
4621void Dictionary<Shape, Key>::SetEntry(int entry,
4622 Object* key,
4623 Object* value) {
4624 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4625}
4626
4627
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004628template<typename Shape, typename Key>
4629void Dictionary<Shape, Key>::SetEntry(int entry,
4630 Object* key,
4631 Object* value,
4632 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004633 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004634 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004635 AssertNoAllocation no_gc;
4636 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004637 FixedArray::set(index, key, mode);
4638 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004639 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004640}
4641
4642
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004643bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4644 ASSERT(other->IsNumber());
4645 return key == static_cast<uint32_t>(other->Number());
4646}
4647
4648
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004649uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
4650 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004651}
4652
4653
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004654uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
4655 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004656 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004657 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004658}
4659
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004660uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
4661 return ComputeIntegerHash(key, seed);
4662}
4663
4664uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
4665 uint32_t seed,
4666 Object* other) {
4667 ASSERT(other->IsNumber());
4668 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
4669}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004670
4671MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4672 return Isolate::Current()->heap()->NumberFromUint32(key);
4673}
4674
4675
4676bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4677 // We know that all entries in a hash table had their hash keys created.
4678 // Use that knowledge to have fast failure.
4679 if (key->Hash() != String::cast(other)->Hash()) return false;
4680 return key->Equals(String::cast(other));
4681}
4682
4683
4684uint32_t StringDictionaryShape::Hash(String* key) {
4685 return key->Hash();
4686}
4687
4688
4689uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4690 return String::cast(other)->Hash();
4691}
4692
4693
4694MaybeObject* StringDictionaryShape::AsObject(String* key) {
4695 return key;
4696}
4697
4698
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004699template <int entrysize>
4700bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4701 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004702}
4703
4704
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004705template <int entrysize>
4706uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004707 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4708 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004709}
4710
4711
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004712template <int entrysize>
4713uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4714 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004715 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4716 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004717}
4718
4719
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004720template <int entrysize>
4721MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004722 return key;
4723}
4724
4725
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004726void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004727 // No write barrier is needed since empty_fixed_array is not in new space.
4728 // Please note this function is used during marking:
4729 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00004730 // - IncrementalMarking::Step
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004731 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4732 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004733}
4734
4735
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004736void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004737 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004738 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004739 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4740 if (elts->length() < required_size) {
4741 // Doubling in size would be overkill, but leave some slack to avoid
4742 // constantly growing.
4743 Expand(required_size + (required_size >> 3));
4744 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004745 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004746 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4747 // Expand will allocate a new backing store in new space even if the size
4748 // we asked for isn't larger than what we had before.
4749 Expand(required_size);
4750 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004751}
4752
4753
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004754void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004755 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004756 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4757}
4758
4759
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004760bool JSArray::AllowsSetElementsLength() {
4761 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4762 ASSERT(result == !HasExternalArrayElements());
4763 return result;
4764}
4765
4766
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004767MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4768 MaybeObject* maybe_result = EnsureCanContainElements(
4769 storage, ALLOW_COPIED_DOUBLE_ELEMENTS);
4770 if (maybe_result->IsFailure()) return maybe_result;
4771 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4772 GetElementsKind() == FAST_DOUBLE_ELEMENTS) ||
4773 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4774 ((GetElementsKind() == FAST_ELEMENTS) ||
4775 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS &&
4776 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004777 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004778 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004779 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004780}
4781
4782
lrn@chromium.org303ada72010-10-27 09:33:13 +00004783MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004784 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004785 return GetHeap()->CopyFixedArray(this);
4786}
4787
4788
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004789MaybeObject* FixedDoubleArray::Copy() {
4790 if (length() == 0) return this;
4791 return GetHeap()->CopyFixedDoubleArray(this);
4792}
4793
4794
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004795void TypeFeedbackCells::SetAstId(int index, Smi* id) {
4796 set(1 + index * 2, id);
4797}
4798
4799
4800Smi* TypeFeedbackCells::AstId(int index) {
4801 return Smi::cast(get(1 + index * 2));
4802}
4803
4804
4805void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
4806 set(index * 2, cell);
4807}
4808
4809
4810JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
4811 return JSGlobalPropertyCell::cast(get(index * 2));
4812}
4813
4814
4815Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
4816 return isolate->factory()->the_hole_value();
4817}
4818
4819
4820Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
4821 return isolate->factory()->undefined_value();
4822}
4823
4824
4825Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
4826 return heap->raw_unchecked_the_hole_value();
4827}
4828
4829
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004830SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00004831SMI_ACCESSORS(TypeFeedbackInfo, ic_with_type_info_count,
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004832 kIcWithTypeinfoCountOffset)
4833ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
4834 kTypeFeedbackCellsOffset)
4835
4836
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00004837SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
4838
4839
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004840Relocatable::Relocatable(Isolate* isolate) {
4841 ASSERT(isolate == Isolate::Current());
4842 isolate_ = isolate;
4843 prev_ = isolate->relocatable_top();
4844 isolate->set_relocatable_top(this);
4845}
4846
4847
4848Relocatable::~Relocatable() {
4849 ASSERT(isolate_ == Isolate::Current());
4850 ASSERT_EQ(isolate_->relocatable_top(), this);
4851 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004852}
4853
4854
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004855int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4856 return map->instance_size();
4857}
4858
4859
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004860void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004861 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004862 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004863}
4864
4865
4866template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004867void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004868 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004869 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004870}
4871
4872
4873void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4874 typedef v8::String::ExternalAsciiStringResource Resource;
4875 v->VisitExternalAsciiString(
4876 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4877}
4878
4879
4880template<typename StaticVisitor>
4881void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4882 typedef v8::String::ExternalAsciiStringResource Resource;
4883 StaticVisitor::VisitExternalAsciiString(
4884 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4885}
4886
4887
4888void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4889 typedef v8::String::ExternalStringResource Resource;
4890 v->VisitExternalTwoByteString(
4891 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4892}
4893
4894
4895template<typename StaticVisitor>
4896void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4897 typedef v8::String::ExternalStringResource Resource;
4898 StaticVisitor::VisitExternalTwoByteString(
4899 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4900}
4901
4902#define SLOT_ADDR(obj, offset) \
4903 reinterpret_cast<Object**>((obj)->address() + offset)
4904
4905template<int start_offset, int end_offset, int size>
4906void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4907 HeapObject* obj,
4908 ObjectVisitor* v) {
4909 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4910}
4911
4912
4913template<int start_offset>
4914void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4915 int object_size,
4916 ObjectVisitor* v) {
4917 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4918}
4919
4920#undef SLOT_ADDR
4921
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004922#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004923#undef CAST_ACCESSOR
4924#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004925#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004926#undef ACCESSORS_TO_SMI
4927#undef SMI_ACCESSORS
4928#undef BOOL_GETTER
4929#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004930#undef FIELD_ADDR
4931#undef READ_FIELD
4932#undef WRITE_FIELD
4933#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004934#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004935#undef READ_DOUBLE_FIELD
4936#undef WRITE_DOUBLE_FIELD
4937#undef READ_INT_FIELD
4938#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004939#undef READ_INTPTR_FIELD
4940#undef WRITE_INTPTR_FIELD
4941#undef READ_UINT32_FIELD
4942#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004943#undef READ_SHORT_FIELD
4944#undef WRITE_SHORT_FIELD
4945#undef READ_BYTE_FIELD
4946#undef WRITE_BYTE_FIELD
4947
4948
4949} } // namespace v8::internal
4950
4951#endif // V8_OBJECTS_INL_H_