blob: 78578cc88427b36b08d8e1b2f97a237fa7178b55 [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() ||
584 map == heap->block_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000585 }
586 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000587}
588
589
590bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000591 return Object::IsHeapObject() &&
592 HeapObject::cast(this)->map() ==
593 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000594}
595
596
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000597bool Object::IsScopeInfo() {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000598 return Object::IsHeapObject() &&
599 HeapObject::cast(this)->map() ==
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000600 HeapObject::cast(this)->GetHeap()->scope_info_map();
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000601}
602
603
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000604TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000605
606
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000607template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000608 return obj->IsJSFunction();
609}
610
611
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000612TYPE_CHECKER(Code, CODE_TYPE)
613TYPE_CHECKER(Oddball, ODDBALL_TYPE)
614TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
615TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
616TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000617TYPE_CHECKER(JSDate, JS_DATE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000618TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000619
620
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000621bool Object::IsStringWrapper() {
622 return IsJSValue() && JSValue::cast(this)->value()->IsString();
623}
624
625
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000626TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000627
628
629bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000630 return IsOddball() &&
631 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000632}
633
634
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000635TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
636TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000637
638
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000639template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000640 return obj->IsJSArray();
641}
642
643
644bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000645 return Object::IsHeapObject() &&
646 HeapObject::cast(this)->map() ==
647 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000648}
649
650
651bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000652 return IsHashTable() &&
653 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000654}
655
656
657bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000658 return IsHashTable() && this ==
659 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000660}
661
662
ager@chromium.orgac091b72010-05-05 07:34:42 +0000663bool Object::IsJSFunctionResultCache() {
664 if (!IsFixedArray()) return false;
665 FixedArray* self = FixedArray::cast(this);
666 int length = self->length();
667 if (length < JSFunctionResultCache::kEntriesIndex) return false;
668 if ((length - JSFunctionResultCache::kEntriesIndex)
669 % JSFunctionResultCache::kEntrySize != 0) {
670 return false;
671 }
672#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000673 if (FLAG_verify_heap) {
674 reinterpret_cast<JSFunctionResultCache*>(this)->
675 JSFunctionResultCacheVerify();
676 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000677#endif
678 return true;
679}
680
681
ricow@chromium.org65fae842010-08-25 15:26:24 +0000682bool Object::IsNormalizedMapCache() {
683 if (!IsFixedArray()) return false;
684 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
685 return false;
686 }
687#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000688 if (FLAG_verify_heap) {
689 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
690 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000691#endif
692 return true;
693}
694
695
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000696bool Object::IsCompilationCacheTable() {
697 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000698}
699
700
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000701bool Object::IsCodeCacheHashTable() {
702 return IsHashTable();
703}
704
705
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000706bool Object::IsPolymorphicCodeCacheHashTable() {
707 return IsHashTable();
708}
709
710
ager@chromium.org236ad962008-09-25 09:45:57 +0000711bool Object::IsMapCache() {
712 return IsHashTable();
713}
714
715
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000716bool Object::IsPrimitive() {
717 return IsOddball() || IsNumber() || IsString();
718}
719
720
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000721bool Object::IsJSGlobalProxy() {
722 bool result = IsHeapObject() &&
723 (HeapObject::cast(this)->map()->instance_type() ==
724 JS_GLOBAL_PROXY_TYPE);
725 ASSERT(!result || IsAccessCheckNeeded());
726 return result;
727}
728
729
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000730bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000731 if (!IsHeapObject()) return false;
732
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000733 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000734 return type == JS_GLOBAL_OBJECT_TYPE ||
735 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000736}
737
738
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000739TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
740TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000741
742
743bool Object::IsUndetectableObject() {
744 return IsHeapObject()
745 && HeapObject::cast(this)->map()->is_undetectable();
746}
747
748
749bool Object::IsAccessCheckNeeded() {
750 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000751 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000752}
753
754
755bool Object::IsStruct() {
756 if (!IsHeapObject()) return false;
757 switch (HeapObject::cast(this)->map()->instance_type()) {
758#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
759 STRUCT_LIST(MAKE_STRUCT_CASE)
760#undef MAKE_STRUCT_CASE
761 default: return false;
762 }
763}
764
765
766#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
767 bool Object::Is##Name() { \
768 return Object::IsHeapObject() \
769 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
770 }
771 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
772#undef MAKE_STRUCT_PREDICATE
773
774
775bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000776 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000777}
778
779
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000780bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000781 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
782}
783
784
785bool Object::IsTheHole() {
786 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000787}
788
789
790bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000791 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000792}
793
794
795bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000796 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000797}
798
799
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000800bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000801 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000802}
803
804
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000805double Object::Number() {
806 ASSERT(IsNumber());
807 return IsSmi()
808 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
809 : reinterpret_cast<HeapNumber*>(this)->value();
810}
811
812
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000813bool Object::IsNaN() {
814 return this->IsHeapNumber() && isnan(HeapNumber::cast(this)->value());
815}
816
817
lrn@chromium.org303ada72010-10-27 09:33:13 +0000818MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000819 if (IsSmi()) return this;
820 if (IsHeapNumber()) {
821 double value = HeapNumber::cast(this)->value();
822 int int_value = FastD2I(value);
823 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
824 return Smi::FromInt(int_value);
825 }
826 }
827 return Failure::Exception();
828}
829
830
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000831bool Object::HasSpecificClassOf(String* name) {
832 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
833}
834
835
lrn@chromium.org303ada72010-10-27 09:33:13 +0000836MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000837 // GetElement can trigger a getter which can cause allocation.
838 // This was not always the case. This ASSERT is here to catch
839 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000840 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000841 return GetElementWithReceiver(this, index);
842}
843
844
lrn@chromium.org303ada72010-10-27 09:33:13 +0000845Object* Object::GetElementNoExceptionThrown(uint32_t index) {
846 MaybeObject* maybe = GetElementWithReceiver(this, index);
847 ASSERT(!maybe->IsFailure());
848 Object* result = NULL; // Initialization to please compiler.
849 maybe->ToObject(&result);
850 return result;
851}
852
853
854MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000855 PropertyAttributes attributes;
856 return GetPropertyWithReceiver(this, key, &attributes);
857}
858
859
lrn@chromium.org303ada72010-10-27 09:33:13 +0000860MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000861 return GetPropertyWithReceiver(this, key, attributes);
862}
863
864
865#define FIELD_ADDR(p, offset) \
866 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
867
868#define READ_FIELD(p, offset) \
869 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
870
871#define WRITE_FIELD(p, offset, value) \
872 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
873
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000874#define WRITE_BARRIER(heap, object, offset, value) \
875 heap->incremental_marking()->RecordWrite( \
876 object, HeapObject::RawField(object, offset), value); \
877 if (heap->InNewSpace(value)) { \
878 heap->RecordWrite(object->address(), offset); \
879 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000880
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000881#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
882 if (mode == UPDATE_WRITE_BARRIER) { \
883 heap->incremental_marking()->RecordWrite( \
884 object, HeapObject::RawField(object, offset), value); \
885 if (heap->InNewSpace(value)) { \
886 heap->RecordWrite(object->address(), offset); \
887 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000888 }
889
lrn@chromium.org7516f052011-03-30 08:52:27 +0000890#ifndef V8_TARGET_ARCH_MIPS
891 #define READ_DOUBLE_FIELD(p, offset) \
892 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
893#else // V8_TARGET_ARCH_MIPS
894 // Prevent gcc from using load-double (mips ldc1) on (possibly)
895 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000896 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000897 union conversion {
898 double d;
899 uint32_t u[2];
900 } c;
901 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
902 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
903 return c.d;
904 }
905 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
906#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000907
lrn@chromium.org7516f052011-03-30 08:52:27 +0000908#ifndef V8_TARGET_ARCH_MIPS
909 #define WRITE_DOUBLE_FIELD(p, offset, value) \
910 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
911#else // V8_TARGET_ARCH_MIPS
912 // Prevent gcc from using store-double (mips sdc1) on (possibly)
913 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000914 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000915 double value) {
916 union conversion {
917 double d;
918 uint32_t u[2];
919 } c;
920 c.d = value;
921 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
922 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
923 }
924 #define WRITE_DOUBLE_FIELD(p, offset, value) \
925 write_double_field(p, offset, value)
926#endif // V8_TARGET_ARCH_MIPS
927
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000928
929#define READ_INT_FIELD(p, offset) \
930 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
931
932#define WRITE_INT_FIELD(p, offset, value) \
933 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
934
ager@chromium.org3e875802009-06-29 08:26:34 +0000935#define READ_INTPTR_FIELD(p, offset) \
936 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
937
938#define WRITE_INTPTR_FIELD(p, offset, value) \
939 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
940
ager@chromium.org7c537e22008-10-16 08:43:32 +0000941#define READ_UINT32_FIELD(p, offset) \
942 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
943
944#define WRITE_UINT32_FIELD(p, offset, value) \
945 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
946
danno@chromium.org88aa0582012-03-23 15:11:57 +0000947#define READ_INT64_FIELD(p, offset) \
948 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)))
949
950#define WRITE_INT64_FIELD(p, offset, value) \
951 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
952
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000953#define READ_SHORT_FIELD(p, offset) \
954 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
955
956#define WRITE_SHORT_FIELD(p, offset, value) \
957 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
958
959#define READ_BYTE_FIELD(p, offset) \
960 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
961
962#define WRITE_BYTE_FIELD(p, offset, value) \
963 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
964
965
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000966Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
967 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000968}
969
970
971int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000972 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000973}
974
975
976Smi* Smi::FromInt(int value) {
977 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000978 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000979 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000980 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000981 return reinterpret_cast<Smi*>(tagged_value);
982}
983
984
985Smi* Smi::FromIntptr(intptr_t value) {
986 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000987 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
988 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000989}
990
991
992Failure::Type Failure::type() const {
993 return static_cast<Type>(value() & kFailureTypeTagMask);
994}
995
996
997bool Failure::IsInternalError() const {
998 return type() == INTERNAL_ERROR;
999}
1000
1001
1002bool Failure::IsOutOfMemoryException() const {
1003 return type() == OUT_OF_MEMORY_EXCEPTION;
1004}
1005
1006
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001007AllocationSpace Failure::allocation_space() const {
1008 ASSERT_EQ(RETRY_AFTER_GC, type());
1009 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1010 & kSpaceTagMask);
1011}
1012
1013
1014Failure* Failure::InternalError() {
1015 return Construct(INTERNAL_ERROR);
1016}
1017
1018
1019Failure* Failure::Exception() {
1020 return Construct(EXCEPTION);
1021}
1022
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001023
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001024Failure* Failure::OutOfMemoryException() {
1025 return Construct(OUT_OF_MEMORY_EXCEPTION);
1026}
1027
1028
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001029intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001030 return static_cast<intptr_t>(
1031 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001032}
1033
1034
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001035Failure* Failure::RetryAfterGC() {
1036 return RetryAfterGC(NEW_SPACE);
1037}
1038
1039
1040Failure* Failure::RetryAfterGC(AllocationSpace space) {
1041 ASSERT((space & ~kSpaceTagMask) == 0);
1042 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001043}
1044
1045
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001046Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001047 uintptr_t info =
1048 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001049 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001050 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001051}
1052
1053
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001054bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001055#ifdef DEBUG
1056 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1057#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001058
1059#ifdef V8_TARGET_ARCH_X64
1060 // To be representable as a long smi, the value must be a 32-bit integer.
1061 bool result = (value == static_cast<int32_t>(value));
1062#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001063 // To be representable as an tagged small integer, the two
1064 // most-significant bits of 'value' must be either 00 or 11 due to
1065 // sign-extension. To check this we add 01 to the two
1066 // most-significant bits, and check if the most-significant bit is 0
1067 //
1068 // CAUTION: The original code below:
1069 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1070 // may lead to incorrect results according to the C language spec, and
1071 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1072 // compiler may produce undefined results in case of signed integer
1073 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001074 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001075#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001076 ASSERT(result == in_range);
1077 return result;
1078}
1079
1080
kasper.lund7276f142008-07-30 08:49:36 +00001081MapWord MapWord::FromMap(Map* map) {
1082 return MapWord(reinterpret_cast<uintptr_t>(map));
1083}
1084
1085
1086Map* MapWord::ToMap() {
1087 return reinterpret_cast<Map*>(value_);
1088}
1089
1090
1091bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001092 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001093}
1094
1095
1096MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001097 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1098 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001099}
1100
1101
1102HeapObject* MapWord::ToForwardingAddress() {
1103 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001104 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001105}
1106
1107
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001108#ifdef DEBUG
1109void HeapObject::VerifyObjectField(int offset) {
1110 VerifyPointer(READ_FIELD(this, offset));
1111}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001112
1113void HeapObject::VerifySmiField(int offset) {
1114 ASSERT(READ_FIELD(this, offset)->IsSmi());
1115}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001116#endif
1117
1118
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001119Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001120 Heap* heap =
1121 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1122 ASSERT(heap != NULL);
1123 ASSERT(heap->isolate() == Isolate::Current());
1124 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001125}
1126
1127
1128Isolate* HeapObject::GetIsolate() {
1129 return GetHeap()->isolate();
1130}
1131
1132
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001133Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001134 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001135}
1136
1137
1138void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001139 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001140 if (value != NULL) {
1141 // TODO(1600) We are passing NULL as a slot because maps can never be on
1142 // evacuation candidate.
1143 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1144 }
1145}
1146
1147
1148// Unsafe accessor omitting write barrier.
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001149void HeapObject::set_map_no_write_barrier(Map* value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001150 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001151}
1152
1153
kasper.lund7276f142008-07-30 08:49:36 +00001154MapWord HeapObject::map_word() {
1155 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1156}
1157
1158
1159void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001160 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001161 // here.
1162 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1163}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001164
1165
1166HeapObject* HeapObject::FromAddress(Address address) {
1167 ASSERT_TAG_ALIGNED(address);
1168 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1169}
1170
1171
1172Address HeapObject::address() {
1173 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1174}
1175
1176
1177int HeapObject::Size() {
1178 return SizeFromMap(map());
1179}
1180
1181
1182void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1183 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1184 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1185}
1186
1187
1188void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1189 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1190}
1191
1192
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001193double HeapNumber::value() {
1194 return READ_DOUBLE_FIELD(this, kValueOffset);
1195}
1196
1197
1198void HeapNumber::set_value(double value) {
1199 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1200}
1201
1202
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001203int HeapNumber::get_exponent() {
1204 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1205 kExponentShift) - kExponentBias;
1206}
1207
1208
1209int HeapNumber::get_sign() {
1210 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1211}
1212
1213
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001214ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001215
1216
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001217Object** FixedArray::GetFirstElementAddress() {
1218 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1219}
1220
1221
1222bool FixedArray::ContainsOnlySmisOrHoles() {
1223 Object* the_hole = GetHeap()->the_hole_value();
1224 Object** current = GetFirstElementAddress();
1225 for (int i = 0; i < length(); ++i) {
1226 Object* candidate = *current++;
1227 if (!candidate->IsSmi() && candidate != the_hole) return false;
1228 }
1229 return true;
1230}
1231
1232
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001233FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001234 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001235 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001236}
1237
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001238void JSObject::ValidateSmiOnlyElements() {
1239#if DEBUG
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001240 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001241 Heap* heap = GetHeap();
1242 // Don't use elements, since integrity checks will fail if there
1243 // are filler pointers in the array.
1244 FixedArray* fixed_array =
1245 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
1246 Map* map = fixed_array->map();
1247 // Arrays that have been shifted in place can't be verified.
1248 if (map != heap->raw_unchecked_one_pointer_filler_map() &&
1249 map != heap->raw_unchecked_two_pointer_filler_map() &&
1250 map != heap->free_space_map()) {
1251 for (int i = 0; i < fixed_array->length(); i++) {
1252 Object* current = fixed_array->get(i);
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001253 ASSERT(current->IsSmi() || current->IsTheHole());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001254 }
1255 }
1256 }
1257#endif
1258}
1259
1260
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001261MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001262#if DEBUG
1263 ValidateSmiOnlyElements();
1264#endif
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001265 if ((map()->elements_kind() != FAST_ELEMENTS)) {
1266 return TransitionElementsKind(FAST_ELEMENTS);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001267 }
1268 return this;
1269}
1270
1271
1272MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001273 uint32_t count,
1274 EnsureElementsMode mode) {
1275 ElementsKind current_kind = map()->elements_kind();
1276 ElementsKind target_kind = current_kind;
1277 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
1278 if (current_kind == FAST_ELEMENTS) return this;
1279
1280 Heap* heap = GetHeap();
1281 Object* the_hole = heap->the_hole_value();
1282 Object* heap_number_map = heap->heap_number_map();
1283 for (uint32_t i = 0; i < count; ++i) {
1284 Object* current = *objects++;
1285 if (!current->IsSmi() && current != the_hole) {
1286 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS &&
1287 HeapObject::cast(current)->map() == heap_number_map) {
1288 target_kind = FAST_DOUBLE_ELEMENTS;
1289 } else {
1290 target_kind = FAST_ELEMENTS;
1291 break;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001292 }
1293 }
1294 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001295
1296 if (target_kind != current_kind) {
1297 return TransitionElementsKind(target_kind);
1298 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001299 return this;
1300}
1301
1302
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001303MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
1304 EnsureElementsMode mode) {
1305 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1306 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1307 elements->map() == GetHeap()->fixed_cow_array_map());
1308 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1309 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1310 }
1311 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
1312 return EnsureCanContainElements(objects, elements->length(), mode);
1313 }
1314
1315 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
1316 if (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) {
1317 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1318 }
1319
1320 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001321}
1322
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001323
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001324MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
1325 ElementsKind to_kind) {
1326 Map* current_map = map();
1327 ElementsKind from_kind = current_map->elements_kind();
1328
1329 if (from_kind == to_kind) return current_map;
1330
1331 Context* global_context = isolate->context()->global_context();
1332 if (current_map == global_context->smi_js_array_map()) {
1333 if (to_kind == FAST_ELEMENTS) {
1334 return global_context->object_js_array_map();
1335 } else {
1336 if (to_kind == FAST_DOUBLE_ELEMENTS) {
1337 return global_context->double_js_array_map();
1338 } else {
1339 ASSERT(to_kind == DICTIONARY_ELEMENTS);
1340 }
1341 }
1342 }
1343 return GetElementsTransitionMapSlow(to_kind);
1344}
1345
1346
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001347void JSObject::set_map_and_elements(Map* new_map,
1348 FixedArrayBase* value,
1349 WriteBarrierMode mode) {
1350 ASSERT(value->HasValidElements());
1351#ifdef DEBUG
1352 ValidateSmiOnlyElements();
1353#endif
1354 if (new_map != NULL) {
1355 if (mode == UPDATE_WRITE_BARRIER) {
1356 set_map(new_map);
1357 } else {
1358 ASSERT(mode == SKIP_WRITE_BARRIER);
1359 set_map_no_write_barrier(new_map);
1360 }
1361 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001362 ASSERT((map()->has_fast_elements() ||
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001363 map()->has_fast_smi_only_elements() ||
1364 (value == GetHeap()->empty_fixed_array())) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001365 (value->map() == GetHeap()->fixed_array_map() ||
1366 value->map() == GetHeap()->fixed_cow_array_map()));
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001367 ASSERT((value == GetHeap()->empty_fixed_array()) ||
1368 (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001369 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001370 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001371}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001372
1373
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001374void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1375 set_map_and_elements(NULL, value, mode);
1376}
1377
1378
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001379void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001380 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1381 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001382}
1383
1384
1385void JSObject::initialize_elements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001386 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001387 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1388 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001389}
1390
1391
lrn@chromium.org303ada72010-10-27 09:33:13 +00001392MaybeObject* JSObject::ResetElements() {
1393 Object* obj;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001394 ElementsKind elements_kind = FLAG_smi_only_arrays
1395 ? FAST_SMI_ONLY_ELEMENTS
1396 : FAST_ELEMENTS;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001397 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(),
1398 elements_kind);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001399 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001400 set_map(Map::cast(obj));
1401 initialize_elements();
1402 return this;
1403}
1404
1405
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001406ACCESSORS(Oddball, to_string, String, kToStringOffset)
1407ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1408
1409
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001410byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001411 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001412}
1413
1414
1415void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001416 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001417}
1418
1419
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001420Object* JSGlobalPropertyCell::value() {
1421 return READ_FIELD(this, kValueOffset);
1422}
1423
1424
1425void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1426 // The write barrier is not used for global property cells.
1427 ASSERT(!val->IsJSGlobalPropertyCell());
1428 WRITE_FIELD(this, kValueOffset, val);
1429}
1430
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001431
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001432int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001433 InstanceType type = map()->instance_type();
1434 // Check for the most common kind of JavaScript object before
1435 // falling into the generic switch. This speeds up the internal
1436 // field operations considerably on average.
1437 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1438 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001439 case JS_GLOBAL_PROXY_TYPE:
1440 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001441 case JS_GLOBAL_OBJECT_TYPE:
1442 return JSGlobalObject::kSize;
1443 case JS_BUILTINS_OBJECT_TYPE:
1444 return JSBuiltinsObject::kSize;
1445 case JS_FUNCTION_TYPE:
1446 return JSFunction::kSize;
1447 case JS_VALUE_TYPE:
1448 return JSValue::kSize;
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00001449 case JS_DATE_TYPE:
1450 return JSDate::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001451 case JS_ARRAY_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001452 return JSArray::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001453 case JS_WEAK_MAP_TYPE:
1454 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001455 case JS_REGEXP_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001456 return JSRegExp::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001457 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001458 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001459 case JS_MESSAGE_OBJECT_TYPE:
1460 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001461 default:
1462 UNREACHABLE();
1463 return 0;
1464 }
1465}
1466
1467
1468int JSObject::GetInternalFieldCount() {
1469 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001470 // Make sure to adjust for the number of in-object properties. These
1471 // properties do contribute to the size, but are not internal fields.
1472 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1473 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001474}
1475
1476
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001477int JSObject::GetInternalFieldOffset(int index) {
1478 ASSERT(index < GetInternalFieldCount() && index >= 0);
1479 return GetHeaderSize() + (kPointerSize * index);
1480}
1481
1482
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001483Object* JSObject::GetInternalField(int index) {
1484 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001485 // Internal objects do follow immediately after the header, whereas in-object
1486 // properties are at the end of the object. Therefore there is no need
1487 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001488 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1489}
1490
1491
1492void JSObject::SetInternalField(int index, Object* value) {
1493 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001494 // Internal objects do follow immediately after the header, whereas in-object
1495 // properties are at the end of the object. Therefore there is no need
1496 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001497 int offset = GetHeaderSize() + (kPointerSize * index);
1498 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001499 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001500}
1501
1502
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001503void JSObject::SetInternalField(int index, Smi* value) {
1504 ASSERT(index < GetInternalFieldCount() && index >= 0);
1505 // 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.
1508 int offset = GetHeaderSize() + (kPointerSize * index);
1509 WRITE_FIELD(this, offset, value);
1510}
1511
1512
ager@chromium.org7c537e22008-10-16 08:43:32 +00001513// Access fast-case object properties at index. The use of these routines
1514// is needed to correctly distinguish between properties stored in-object and
1515// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001516Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001517 // Adjust for the number of properties stored in the object.
1518 index -= map()->inobject_properties();
1519 if (index < 0) {
1520 int offset = map()->instance_size() + (index * kPointerSize);
1521 return READ_FIELD(this, offset);
1522 } else {
1523 ASSERT(index < properties()->length());
1524 return properties()->get(index);
1525 }
1526}
1527
1528
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001529Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001530 // Adjust for the number of properties stored in the object.
1531 index -= map()->inobject_properties();
1532 if (index < 0) {
1533 int offset = map()->instance_size() + (index * kPointerSize);
1534 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001535 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001536 } else {
1537 ASSERT(index < properties()->length());
1538 properties()->set(index, value);
1539 }
1540 return value;
1541}
1542
1543
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001544int JSObject::GetInObjectPropertyOffset(int index) {
1545 // Adjust for the number of properties stored in the object.
1546 index -= map()->inobject_properties();
1547 ASSERT(index < 0);
1548 return map()->instance_size() + (index * kPointerSize);
1549}
1550
1551
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001552Object* JSObject::InObjectPropertyAt(int index) {
1553 // Adjust for the number of properties stored in the object.
1554 index -= map()->inobject_properties();
1555 ASSERT(index < 0);
1556 int offset = map()->instance_size() + (index * kPointerSize);
1557 return READ_FIELD(this, offset);
1558}
1559
1560
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001561Object* JSObject::InObjectPropertyAtPut(int index,
1562 Object* value,
1563 WriteBarrierMode mode) {
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 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001569 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001570 return value;
1571}
1572
1573
1574
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001575void JSObject::InitializeBody(Map* map,
1576 Object* pre_allocated_value,
1577 Object* filler_value) {
1578 ASSERT(!filler_value->IsHeapObject() ||
1579 !GetHeap()->InNewSpace(filler_value));
1580 ASSERT(!pre_allocated_value->IsHeapObject() ||
1581 !GetHeap()->InNewSpace(pre_allocated_value));
1582 int size = map->instance_size();
1583 int offset = kHeaderSize;
1584 if (filler_value != pre_allocated_value) {
1585 int pre_allocated = map->pre_allocated_property_fields();
1586 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1587 for (int i = 0; i < pre_allocated; i++) {
1588 WRITE_FIELD(this, offset, pre_allocated_value);
1589 offset += kPointerSize;
1590 }
1591 }
1592 while (offset < size) {
1593 WRITE_FIELD(this, offset, filler_value);
1594 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001595 }
1596}
1597
1598
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001599bool JSObject::HasFastProperties() {
1600 return !properties()->IsDictionary();
1601}
1602
1603
1604int JSObject::MaxFastProperties() {
1605 // Allow extra fast properties if the object has more than
1606 // kMaxFastProperties in-object properties. When this is the case,
1607 // it is very unlikely that the object is being used as a dictionary
1608 // and there is a good chance that allowing more map transitions
1609 // will be worth it.
1610 return Max(map()->inobject_properties(), kMaxFastProperties);
1611}
1612
1613
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001614void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001615 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001616 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001617 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001618 }
1619}
1620
1621
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001622bool Object::ToArrayIndex(uint32_t* index) {
1623 if (IsSmi()) {
1624 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001625 if (value < 0) return false;
1626 *index = value;
1627 return true;
1628 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001629 if (IsHeapNumber()) {
1630 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001631 uint32_t uint_value = static_cast<uint32_t>(value);
1632 if (value == static_cast<double>(uint_value)) {
1633 *index = uint_value;
1634 return true;
1635 }
1636 }
1637 return false;
1638}
1639
1640
1641bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1642 if (!this->IsJSValue()) return false;
1643
1644 JSValue* js_value = JSValue::cast(this);
1645 if (!js_value->value()->IsString()) return false;
1646
1647 String* str = String::cast(js_value->value());
1648 if (index >= (uint32_t)str->length()) return false;
1649
1650 return true;
1651}
1652
1653
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001654FixedArrayBase* FixedArrayBase::cast(Object* object) {
1655 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1656 return reinterpret_cast<FixedArrayBase*>(object);
1657}
1658
1659
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001660Object* FixedArray::get(int index) {
1661 ASSERT(index >= 0 && index < this->length());
1662 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1663}
1664
1665
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001666void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001667 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001668 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001669 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1670 int offset = kHeaderSize + index * kPointerSize;
1671 WRITE_FIELD(this, offset, value);
1672}
1673
1674
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001675void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001676 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001677 ASSERT(index >= 0 && index < this->length());
1678 int offset = kHeaderSize + index * kPointerSize;
1679 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001680 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001681}
1682
1683
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001684inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1685 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1686}
1687
1688
1689inline double FixedDoubleArray::hole_nan_as_double() {
1690 return BitCast<double, uint64_t>(kHoleNanInt64);
1691}
1692
1693
1694inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1695 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1696 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1697 return OS::nan_value();
1698}
1699
1700
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001701double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001702 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1703 map() != HEAP->fixed_array_map());
1704 ASSERT(index >= 0 && index < this->length());
1705 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1706 ASSERT(!is_the_hole_nan(result));
1707 return result;
1708}
1709
danno@chromium.org88aa0582012-03-23 15:11:57 +00001710int64_t FixedDoubleArray::get_representation(int index) {
1711 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1712 map() != HEAP->fixed_array_map());
1713 ASSERT(index >= 0 && index < this->length());
1714 return READ_INT64_FIELD(this, kHeaderSize + index * kDoubleSize);
1715}
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001716
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001717MaybeObject* FixedDoubleArray::get(int index) {
1718 if (is_the_hole(index)) {
1719 return GetHeap()->the_hole_value();
1720 } else {
1721 return GetHeap()->NumberFromDouble(get_scalar(index));
1722 }
1723}
1724
1725
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001726void FixedDoubleArray::set(int index, double value) {
1727 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1728 map() != HEAP->fixed_array_map());
1729 int offset = kHeaderSize + index * kDoubleSize;
1730 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1731 WRITE_DOUBLE_FIELD(this, offset, value);
1732}
1733
1734
1735void FixedDoubleArray::set_the_hole(int index) {
1736 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1737 map() != HEAP->fixed_array_map());
1738 int offset = kHeaderSize + index * kDoubleSize;
1739 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1740}
1741
1742
1743bool FixedDoubleArray::is_the_hole(int index) {
1744 int offset = kHeaderSize + index * kDoubleSize;
1745 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1746}
1747
1748
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001749WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001750 Heap* heap = GetHeap();
1751 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1752 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001753 return UPDATE_WRITE_BARRIER;
1754}
1755
1756
1757void FixedArray::set(int index,
1758 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001759 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001760 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001761 ASSERT(index >= 0 && index < this->length());
1762 int offset = kHeaderSize + index * kPointerSize;
1763 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001764 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001765}
1766
1767
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001768void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1769 int index,
1770 Object* value) {
1771 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
1772 ASSERT(index >= 0 && index < array->length());
1773 int offset = kHeaderSize + index * kPointerSize;
1774 WRITE_FIELD(array, offset, value);
1775 Heap* heap = array->GetHeap();
1776 if (heap->InNewSpace(value)) {
1777 heap->RecordWrite(array->address(), offset);
1778 }
1779}
1780
1781
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001782void FixedArray::NoWriteBarrierSet(FixedArray* array,
1783 int index,
1784 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001785 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001786 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001787 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001788 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1789}
1790
1791
1792void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001793 ASSERT(map() != HEAP->fixed_cow_array_map());
1794 set_undefined(GetHeap(), index);
1795}
1796
1797
1798void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001799 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001800 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001801 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001802 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001803}
1804
1805
ager@chromium.org236ad962008-09-25 09:45:57 +00001806void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001807 set_null(GetHeap(), index);
1808}
1809
1810
1811void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001812 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001813 ASSERT(!heap->InNewSpace(heap->null_value()));
1814 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001815}
1816
1817
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001818void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001819 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001820 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001821 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1822 WRITE_FIELD(this,
1823 kHeaderSize + index * kPointerSize,
1824 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001825}
1826
1827
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001828void FixedArray::set_unchecked(int index, Smi* value) {
1829 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1830 int offset = kHeaderSize + index * kPointerSize;
1831 WRITE_FIELD(this, offset, value);
1832}
1833
1834
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001835void FixedArray::set_unchecked(Heap* heap,
1836 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001837 Object* value,
1838 WriteBarrierMode mode) {
1839 int offset = kHeaderSize + index * kPointerSize;
1840 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001841 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001842}
1843
1844
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001845void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001846 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001847 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1848 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001849}
1850
1851
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001852Object** FixedArray::data_start() {
1853 return HeapObject::RawField(this, kHeaderSize);
1854}
1855
1856
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001857bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001858 ASSERT(this->IsSmi() ||
1859 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001860 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001861 return this->IsSmi() || length() <= kFirstIndex;
1862}
1863
1864
1865int DescriptorArray::bit_field3_storage() {
1866 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1867 return Smi::cast(storage)->value();
1868}
1869
1870void DescriptorArray::set_bit_field3_storage(int value) {
1871 ASSERT(!IsEmpty());
1872 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001873}
1874
1875
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001876void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1877 int first,
1878 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001879 Object* tmp = array->get(first);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001880 NoIncrementalWriteBarrierSet(array, first, array->get(second));
1881 NoIncrementalWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001882}
1883
1884
1885int DescriptorArray::Search(String* name) {
1886 SLOW_ASSERT(IsSortedNoDuplicates());
1887
1888 // Check for empty descriptor array.
1889 int nof = number_of_descriptors();
1890 if (nof == 0) return kNotFound;
1891
1892 // Fast case: do linear search for small arrays.
1893 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001894 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001895 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001896 }
1897
1898 // Slow case: perform binary search.
1899 return BinarySearch(name, 0, nof - 1);
1900}
1901
1902
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001903int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001904 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001905 if (number == DescriptorLookupCache::kAbsent) {
1906 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001907 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001908 }
1909 return number;
1910}
1911
1912
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001913String* DescriptorArray::GetKey(int descriptor_number) {
1914 ASSERT(descriptor_number < number_of_descriptors());
1915 return String::cast(get(ToKeyIndex(descriptor_number)));
1916}
1917
1918
1919Object* DescriptorArray::GetValue(int descriptor_number) {
1920 ASSERT(descriptor_number < number_of_descriptors());
1921 return GetContentArray()->get(ToValueIndex(descriptor_number));
1922}
1923
1924
1925Smi* DescriptorArray::GetDetails(int descriptor_number) {
1926 ASSERT(descriptor_number < number_of_descriptors());
1927 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1928}
1929
1930
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001931PropertyType DescriptorArray::GetType(int descriptor_number) {
1932 ASSERT(descriptor_number < number_of_descriptors());
1933 return PropertyDetails(GetDetails(descriptor_number)).type();
1934}
1935
1936
1937int DescriptorArray::GetFieldIndex(int descriptor_number) {
1938 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1939}
1940
1941
1942JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1943 return JSFunction::cast(GetValue(descriptor_number));
1944}
1945
1946
1947Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1948 ASSERT(GetType(descriptor_number) == CALLBACKS);
1949 return GetValue(descriptor_number);
1950}
1951
1952
1953AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1954 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001955 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001956 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001957}
1958
1959
1960bool DescriptorArray::IsProperty(int descriptor_number) {
ulan@chromium.org9a21ec42012-03-06 08:42:24 +00001961 Entry entry(this, descriptor_number);
1962 return IsPropertyDescriptor(&entry);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001963}
1964
1965
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001966bool DescriptorArray::IsTransitionOnly(int descriptor_number) {
1967 switch (GetType(descriptor_number)) {
1968 case MAP_TRANSITION:
1969 case CONSTANT_TRANSITION:
1970 case ELEMENTS_TRANSITION:
1971 return true;
1972 case CALLBACKS: {
1973 Object* value = GetValue(descriptor_number);
1974 if (!value->IsAccessorPair()) return false;
1975 AccessorPair* accessors = AccessorPair::cast(value);
1976 return accessors->getter()->IsMap() && accessors->setter()->IsMap();
1977 }
1978 case NORMAL:
1979 case FIELD:
1980 case CONSTANT_FUNCTION:
1981 case HANDLER:
1982 case INTERCEPTOR:
1983 case NULL_DESCRIPTOR:
1984 return false;
1985 }
1986 UNREACHABLE(); // Keep the compiler happy.
1987 return false;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001988}
1989
1990
1991bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1992 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1993}
1994
1995
1996bool DescriptorArray::IsDontEnum(int descriptor_number) {
1997 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1998}
1999
2000
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002001void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2002 desc->Init(GetKey(descriptor_number),
2003 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002004 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002005}
2006
2007
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002008void DescriptorArray::Set(int descriptor_number,
2009 Descriptor* desc,
2010 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002011 // Range check.
2012 ASSERT(descriptor_number < number_of_descriptors());
2013
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002014 NoIncrementalWriteBarrierSet(this,
2015 ToKeyIndex(descriptor_number),
2016 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002017 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002018 NoIncrementalWriteBarrierSet(content_array,
2019 ToValueIndex(descriptor_number),
2020 desc->GetValue());
2021 NoIncrementalWriteBarrierSet(content_array,
2022 ToDetailsIndex(descriptor_number),
2023 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002024}
2025
2026
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002027void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2028 int first, int second) {
2029 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002030 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002031 NoIncrementalWriteBarrierSwap(content_array,
2032 ToValueIndex(first),
2033 ToValueIndex(second));
2034 NoIncrementalWriteBarrierSwap(content_array,
2035 ToDetailsIndex(first),
2036 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002037}
2038
2039
2040DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
2041 : marking_(array->GetHeap()->incremental_marking()) {
2042 marking_->EnterNoMarkingScope();
2043 if (array->number_of_descriptors() > 0) {
2044 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
2045 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
2046 }
2047}
2048
2049
2050DescriptorArray::WhitenessWitness::~WhitenessWitness() {
2051 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002052}
2053
2054
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002055template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002056int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2057 const int kMinCapacity = 32;
2058 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2059 if (capacity < kMinCapacity) {
2060 capacity = kMinCapacity; // Guarantee min capacity.
2061 }
2062 return capacity;
2063}
2064
2065
2066template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002067int HashTable<Shape, Key>::FindEntry(Key key) {
2068 return FindEntry(GetIsolate(), key);
2069}
2070
2071
2072// Find entry for key otherwise return kNotFound.
2073template<typename Shape, typename Key>
2074int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2075 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002076 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002077 uint32_t count = 1;
2078 // EnsureCapacity will guarantee the hash table is never full.
2079 while (true) {
2080 Object* element = KeyAt(entry);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002081 // Empty entry.
2082 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2083 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002084 Shape::IsMatch(key, element)) return entry;
2085 entry = NextProbe(entry, count++, capacity);
2086 }
2087 return kNotFound;
2088}
2089
2090
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002091bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002092 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002093 if (!max_index_object->IsSmi()) return false;
2094 return 0 !=
2095 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2096}
2097
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002098uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002099 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002100 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002101 if (!max_index_object->IsSmi()) return 0;
2102 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2103 return value >> kRequiresSlowElementsTagSize;
2104}
2105
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002106void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002107 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002108}
2109
2110
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002111// ------------------------------------
2112// Cast operations
2113
2114
2115CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002116CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002117CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002118CAST_ACCESSOR(DeoptimizationInputData)
2119CAST_ACCESSOR(DeoptimizationOutputData)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002120CAST_ACCESSOR(TypeFeedbackCells)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002121CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002122CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002123CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002124CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002125CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002126CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002127CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002128CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002129CAST_ACCESSOR(String)
2130CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002131CAST_ACCESSOR(SeqAsciiString)
2132CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002133CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002134CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002135CAST_ACCESSOR(ExternalString)
2136CAST_ACCESSOR(ExternalAsciiString)
2137CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002138CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002139CAST_ACCESSOR(JSObject)
2140CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002141CAST_ACCESSOR(HeapObject)
2142CAST_ACCESSOR(HeapNumber)
2143CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002144CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002145CAST_ACCESSOR(SharedFunctionInfo)
2146CAST_ACCESSOR(Map)
2147CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002148CAST_ACCESSOR(GlobalObject)
2149CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002150CAST_ACCESSOR(JSGlobalObject)
2151CAST_ACCESSOR(JSBuiltinsObject)
2152CAST_ACCESSOR(Code)
2153CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002154CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002155CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002156CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002157CAST_ACCESSOR(JSSet)
2158CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002159CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002160CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002161CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002162CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002163CAST_ACCESSOR(ExternalArray)
2164CAST_ACCESSOR(ExternalByteArray)
2165CAST_ACCESSOR(ExternalUnsignedByteArray)
2166CAST_ACCESSOR(ExternalShortArray)
2167CAST_ACCESSOR(ExternalUnsignedShortArray)
2168CAST_ACCESSOR(ExternalIntArray)
2169CAST_ACCESSOR(ExternalUnsignedIntArray)
2170CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002171CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002172CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002173CAST_ACCESSOR(Struct)
2174
2175
2176#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2177 STRUCT_LIST(MAKE_STRUCT_CAST)
2178#undef MAKE_STRUCT_CAST
2179
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002180
2181template <typename Shape, typename Key>
2182HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002183 ASSERT(obj->IsHashTable());
2184 return reinterpret_cast<HashTable*>(obj);
2185}
2186
2187
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002188SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002189SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002190
ager@chromium.orgac091b72010-05-05 07:34:42 +00002191SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002192
2193
2194uint32_t String::hash_field() {
2195 return READ_UINT32_FIELD(this, kHashFieldOffset);
2196}
2197
2198
2199void String::set_hash_field(uint32_t value) {
2200 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002201#if V8_HOST_ARCH_64_BIT
2202 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2203#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002204}
2205
2206
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002207bool String::Equals(String* other) {
2208 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002209 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2210 return false;
2211 }
2212 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002213}
2214
2215
lrn@chromium.org303ada72010-10-27 09:33:13 +00002216MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002217 if (!StringShape(this).IsCons()) return this;
2218 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002219 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002220 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002221}
2222
2223
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002224String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002225 MaybeObject* flat = TryFlatten(pretenure);
2226 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002227 if (!flat->ToObject(&successfully_flattened)) return this;
2228 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002229}
2230
2231
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002232uint16_t String::Get(int index) {
2233 ASSERT(index >= 0 && index < length());
2234 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002235 case kSeqStringTag | kAsciiStringTag:
2236 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2237 case kSeqStringTag | kTwoByteStringTag:
2238 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2239 case kConsStringTag | kAsciiStringTag:
2240 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002241 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002242 case kExternalStringTag | kAsciiStringTag:
2243 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2244 case kExternalStringTag | kTwoByteStringTag:
2245 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002246 case kSlicedStringTag | kAsciiStringTag:
2247 case kSlicedStringTag | kTwoByteStringTag:
2248 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002249 default:
2250 break;
2251 }
2252
2253 UNREACHABLE();
2254 return 0;
2255}
2256
2257
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002258void String::Set(int index, uint16_t value) {
2259 ASSERT(index >= 0 && index < length());
2260 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002261
ager@chromium.org5ec48922009-05-05 07:25:34 +00002262 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002263 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2264 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002265}
2266
2267
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002268bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002269 if (!StringShape(this).IsCons()) return true;
2270 return ConsString::cast(this)->second()->length() == 0;
2271}
2272
2273
2274String* String::GetUnderlying() {
2275 // Giving direct access to underlying string only makes sense if the
2276 // wrapping string is already flattened.
2277 ASSERT(this->IsFlat());
2278 ASSERT(StringShape(this).IsIndirect());
2279 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2280 const int kUnderlyingOffset = SlicedString::kParentOffset;
2281 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002282}
2283
2284
ager@chromium.org7c537e22008-10-16 08:43:32 +00002285uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002286 ASSERT(index >= 0 && index < length());
2287 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2288}
2289
2290
ager@chromium.org7c537e22008-10-16 08:43:32 +00002291void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002292 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2293 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2294 static_cast<byte>(value));
2295}
2296
2297
ager@chromium.org7c537e22008-10-16 08:43:32 +00002298Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002299 return FIELD_ADDR(this, kHeaderSize);
2300}
2301
2302
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002303char* SeqAsciiString::GetChars() {
2304 return reinterpret_cast<char*>(GetCharsAddress());
2305}
2306
2307
ager@chromium.org7c537e22008-10-16 08:43:32 +00002308Address SeqTwoByteString::GetCharsAddress() {
2309 return FIELD_ADDR(this, kHeaderSize);
2310}
2311
2312
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002313uc16* SeqTwoByteString::GetChars() {
2314 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2315}
2316
2317
ager@chromium.org7c537e22008-10-16 08:43:32 +00002318uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002319 ASSERT(index >= 0 && index < length());
2320 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2321}
2322
2323
ager@chromium.org7c537e22008-10-16 08:43:32 +00002324void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002325 ASSERT(index >= 0 && index < length());
2326 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2327}
2328
2329
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002330int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002331 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002332}
2333
2334
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002335int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002336 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002337}
2338
2339
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002340String* SlicedString::parent() {
2341 return String::cast(READ_FIELD(this, kParentOffset));
2342}
2343
2344
2345void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002346 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002347 WRITE_FIELD(this, kParentOffset, parent);
2348}
2349
2350
2351SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2352
2353
ager@chromium.org870a0b62008-11-04 11:43:05 +00002354String* ConsString::first() {
2355 return String::cast(READ_FIELD(this, kFirstOffset));
2356}
2357
2358
2359Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002360 return READ_FIELD(this, kFirstOffset);
2361}
2362
2363
ager@chromium.org870a0b62008-11-04 11:43:05 +00002364void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002365 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002366 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002367}
2368
2369
ager@chromium.org870a0b62008-11-04 11:43:05 +00002370String* ConsString::second() {
2371 return String::cast(READ_FIELD(this, kSecondOffset));
2372}
2373
2374
2375Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002376 return READ_FIELD(this, kSecondOffset);
2377}
2378
2379
ager@chromium.org870a0b62008-11-04 11:43:05 +00002380void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002381 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002382 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002383}
2384
2385
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002386bool ExternalString::is_short() {
2387 InstanceType type = map()->instance_type();
2388 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002389}
2390
2391
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002392const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002393 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2394}
2395
2396
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002397void ExternalAsciiString::update_data_cache() {
2398 if (is_short()) return;
2399 const char** data_field =
2400 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2401 *data_field = resource()->data();
2402}
2403
2404
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002405void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002406 const ExternalAsciiString::Resource* resource) {
2407 *reinterpret_cast<const Resource**>(
2408 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002409 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002410}
2411
2412
2413const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002414 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002415}
2416
2417
2418uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2419 ASSERT(index >= 0 && index < length());
2420 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002421}
2422
2423
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002424const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002425 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2426}
2427
2428
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002429void ExternalTwoByteString::update_data_cache() {
2430 if (is_short()) return;
2431 const uint16_t** data_field =
2432 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2433 *data_field = resource()->data();
2434}
2435
2436
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002437void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002438 const ExternalTwoByteString::Resource* resource) {
2439 *reinterpret_cast<const Resource**>(
2440 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002441 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002442}
2443
2444
2445const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002446 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002447}
2448
2449
2450uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2451 ASSERT(index >= 0 && index < length());
2452 return GetChars()[index];
2453}
2454
2455
2456const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2457 unsigned start) {
2458 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002459}
2460
2461
ager@chromium.orgac091b72010-05-05 07:34:42 +00002462void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002463 set_finger_index(kEntriesIndex);
2464 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002465}
2466
2467
2468void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002469 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002470 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002471 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002472 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002473 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002474 MakeZeroSize();
2475}
2476
2477
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002478int JSFunctionResultCache::size() {
2479 return Smi::cast(get(kCacheSizeIndex))->value();
2480}
2481
2482
2483void JSFunctionResultCache::set_size(int size) {
2484 set(kCacheSizeIndex, Smi::FromInt(size));
2485}
2486
2487
2488int JSFunctionResultCache::finger_index() {
2489 return Smi::cast(get(kFingerIndex))->value();
2490}
2491
2492
2493void JSFunctionResultCache::set_finger_index(int finger_index) {
2494 set(kFingerIndex, Smi::FromInt(finger_index));
2495}
2496
2497
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002498byte ByteArray::get(int index) {
2499 ASSERT(index >= 0 && index < this->length());
2500 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2501}
2502
2503
2504void ByteArray::set(int index, byte value) {
2505 ASSERT(index >= 0 && index < this->length());
2506 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2507}
2508
2509
2510int ByteArray::get_int(int index) {
2511 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2512 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2513}
2514
2515
2516ByteArray* ByteArray::FromDataStartAddress(Address address) {
2517 ASSERT_TAG_ALIGNED(address);
2518 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2519}
2520
2521
2522Address ByteArray::GetDataStartAddress() {
2523 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2524}
2525
2526
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002527uint8_t* ExternalPixelArray::external_pixel_pointer() {
2528 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002529}
2530
2531
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002532uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002533 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002534 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002535 return ptr[index];
2536}
2537
2538
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002539MaybeObject* ExternalPixelArray::get(int index) {
2540 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2541}
2542
2543
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002544void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002545 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002546 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002547 ptr[index] = value;
2548}
2549
2550
ager@chromium.org3811b432009-10-28 14:53:37 +00002551void* ExternalArray::external_pointer() {
2552 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2553 return reinterpret_cast<void*>(ptr);
2554}
2555
2556
2557void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2558 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2559 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2560}
2561
2562
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002563int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002564 ASSERT((index >= 0) && (index < this->length()));
2565 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2566 return ptr[index];
2567}
2568
2569
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002570MaybeObject* ExternalByteArray::get(int index) {
2571 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2572}
2573
2574
ager@chromium.org3811b432009-10-28 14:53:37 +00002575void ExternalByteArray::set(int index, int8_t value) {
2576 ASSERT((index >= 0) && (index < this->length()));
2577 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2578 ptr[index] = value;
2579}
2580
2581
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002582uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002583 ASSERT((index >= 0) && (index < this->length()));
2584 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2585 return ptr[index];
2586}
2587
2588
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002589MaybeObject* ExternalUnsignedByteArray::get(int index) {
2590 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2591}
2592
2593
ager@chromium.org3811b432009-10-28 14:53:37 +00002594void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2595 ASSERT((index >= 0) && (index < this->length()));
2596 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2597 ptr[index] = value;
2598}
2599
2600
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002601int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002602 ASSERT((index >= 0) && (index < this->length()));
2603 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2604 return ptr[index];
2605}
2606
2607
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002608MaybeObject* ExternalShortArray::get(int index) {
2609 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2610}
2611
2612
ager@chromium.org3811b432009-10-28 14:53:37 +00002613void ExternalShortArray::set(int index, int16_t value) {
2614 ASSERT((index >= 0) && (index < this->length()));
2615 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2616 ptr[index] = value;
2617}
2618
2619
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002620uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002621 ASSERT((index >= 0) && (index < this->length()));
2622 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2623 return ptr[index];
2624}
2625
2626
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002627MaybeObject* ExternalUnsignedShortArray::get(int index) {
2628 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2629}
2630
2631
ager@chromium.org3811b432009-10-28 14:53:37 +00002632void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2633 ASSERT((index >= 0) && (index < this->length()));
2634 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2635 ptr[index] = value;
2636}
2637
2638
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002639int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002640 ASSERT((index >= 0) && (index < this->length()));
2641 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2642 return ptr[index];
2643}
2644
2645
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002646MaybeObject* ExternalIntArray::get(int index) {
2647 return GetHeap()->NumberFromInt32(get_scalar(index));
2648}
2649
2650
ager@chromium.org3811b432009-10-28 14:53:37 +00002651void ExternalIntArray::set(int index, int32_t value) {
2652 ASSERT((index >= 0) && (index < this->length()));
2653 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2654 ptr[index] = value;
2655}
2656
2657
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002658uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002659 ASSERT((index >= 0) && (index < this->length()));
2660 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2661 return ptr[index];
2662}
2663
2664
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002665MaybeObject* ExternalUnsignedIntArray::get(int index) {
2666 return GetHeap()->NumberFromUint32(get_scalar(index));
2667}
2668
2669
ager@chromium.org3811b432009-10-28 14:53:37 +00002670void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2671 ASSERT((index >= 0) && (index < this->length()));
2672 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2673 ptr[index] = value;
2674}
2675
2676
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002677float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002678 ASSERT((index >= 0) && (index < this->length()));
2679 float* ptr = static_cast<float*>(external_pointer());
2680 return ptr[index];
2681}
2682
2683
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002684MaybeObject* ExternalFloatArray::get(int index) {
2685 return GetHeap()->NumberFromDouble(get_scalar(index));
2686}
2687
2688
ager@chromium.org3811b432009-10-28 14:53:37 +00002689void ExternalFloatArray::set(int index, float value) {
2690 ASSERT((index >= 0) && (index < this->length()));
2691 float* ptr = static_cast<float*>(external_pointer());
2692 ptr[index] = value;
2693}
2694
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002695
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002696double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002697 ASSERT((index >= 0) && (index < this->length()));
2698 double* ptr = static_cast<double*>(external_pointer());
2699 return ptr[index];
2700}
2701
2702
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002703MaybeObject* ExternalDoubleArray::get(int index) {
2704 return GetHeap()->NumberFromDouble(get_scalar(index));
2705}
2706
2707
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002708void ExternalDoubleArray::set(int index, double value) {
2709 ASSERT((index >= 0) && (index < this->length()));
2710 double* ptr = static_cast<double*>(external_pointer());
2711 ptr[index] = value;
2712}
2713
2714
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002715int Map::visitor_id() {
2716 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2717}
2718
2719
2720void Map::set_visitor_id(int id) {
2721 ASSERT(0 <= id && id < 256);
2722 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2723}
2724
ager@chromium.org3811b432009-10-28 14:53:37 +00002725
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002726int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002727 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2728}
2729
2730
2731int Map::inobject_properties() {
2732 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002733}
2734
2735
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002736int Map::pre_allocated_property_fields() {
2737 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2738}
2739
2740
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002741int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002742 int instance_size = map->instance_size();
2743 if (instance_size != kVariableSizeSentinel) return instance_size;
2744 // We can ignore the "symbol" bit becase it is only set for symbols
2745 // and implies a string type.
2746 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002747 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002748 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002749 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002750 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002751 if (instance_type == ASCII_STRING_TYPE) {
2752 return SeqAsciiString::SizeFor(
2753 reinterpret_cast<SeqAsciiString*>(this)->length());
2754 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002755 if (instance_type == BYTE_ARRAY_TYPE) {
2756 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2757 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002758 if (instance_type == FREE_SPACE_TYPE) {
2759 return reinterpret_cast<FreeSpace*>(this)->size();
2760 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002761 if (instance_type == STRING_TYPE) {
2762 return SeqTwoByteString::SizeFor(
2763 reinterpret_cast<SeqTwoByteString*>(this)->length());
2764 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002765 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2766 return FixedDoubleArray::SizeFor(
2767 reinterpret_cast<FixedDoubleArray*>(this)->length());
2768 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002769 ASSERT(instance_type == CODE_TYPE);
2770 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002771}
2772
2773
2774void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002775 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002776 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002777 ASSERT(0 <= value && value < 256);
2778 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2779}
2780
2781
ager@chromium.org7c537e22008-10-16 08:43:32 +00002782void Map::set_inobject_properties(int value) {
2783 ASSERT(0 <= value && value < 256);
2784 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2785}
2786
2787
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002788void Map::set_pre_allocated_property_fields(int value) {
2789 ASSERT(0 <= value && value < 256);
2790 WRITE_BYTE_FIELD(this,
2791 kPreAllocatedPropertyFieldsOffset,
2792 static_cast<byte>(value));
2793}
2794
2795
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002796InstanceType Map::instance_type() {
2797 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2798}
2799
2800
2801void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002802 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2803}
2804
2805
2806int Map::unused_property_fields() {
2807 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2808}
2809
2810
2811void Map::set_unused_property_fields(int value) {
2812 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2813}
2814
2815
2816byte Map::bit_field() {
2817 return READ_BYTE_FIELD(this, kBitFieldOffset);
2818}
2819
2820
2821void Map::set_bit_field(byte value) {
2822 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2823}
2824
2825
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002826byte Map::bit_field2() {
2827 return READ_BYTE_FIELD(this, kBitField2Offset);
2828}
2829
2830
2831void Map::set_bit_field2(byte value) {
2832 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2833}
2834
2835
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002836void Map::set_non_instance_prototype(bool value) {
2837 if (value) {
2838 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2839 } else {
2840 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2841 }
2842}
2843
2844
2845bool Map::has_non_instance_prototype() {
2846 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2847}
2848
2849
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002850void Map::set_function_with_prototype(bool value) {
2851 if (value) {
2852 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2853 } else {
2854 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2855 }
2856}
2857
2858
2859bool Map::function_with_prototype() {
2860 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2861}
2862
2863
ager@chromium.org870a0b62008-11-04 11:43:05 +00002864void Map::set_is_access_check_needed(bool access_check_needed) {
2865 if (access_check_needed) {
2866 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2867 } else {
2868 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2869 }
2870}
2871
2872
2873bool Map::is_access_check_needed() {
2874 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2875}
2876
2877
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002878void Map::set_is_extensible(bool value) {
2879 if (value) {
2880 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2881 } else {
2882 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2883 }
2884}
2885
2886bool Map::is_extensible() {
2887 return ((1 << kIsExtensible) & bit_field2()) != 0;
2888}
2889
2890
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002891void Map::set_attached_to_shared_function_info(bool value) {
2892 if (value) {
2893 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2894 } else {
2895 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2896 }
2897}
2898
2899bool Map::attached_to_shared_function_info() {
2900 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2901}
2902
2903
2904void Map::set_is_shared(bool value) {
2905 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002906 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002907 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002908 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002909 }
2910}
2911
2912bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002913 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002914}
2915
2916
2917JSFunction* Map::unchecked_constructor() {
2918 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2919}
2920
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002921
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002922Code::Flags Code::flags() {
2923 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2924}
2925
2926
2927void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002928 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002929 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002930 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2931 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002932 ExtractArgumentsCountFromFlags(flags) >= 0);
2933 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2934}
2935
2936
2937Code::Kind Code::kind() {
2938 return ExtractKindFromFlags(flags());
2939}
2940
2941
kasper.lund7276f142008-07-30 08:49:36 +00002942InlineCacheState Code::ic_state() {
2943 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002944 // Only allow uninitialized or debugger states for non-IC code
2945 // objects. This is used in the debugger to determine whether or not
2946 // a call to code object has been replaced with a debug break call.
2947 ASSERT(is_inline_cache_stub() ||
2948 result == UNINITIALIZED ||
2949 result == DEBUG_BREAK ||
2950 result == DEBUG_PREPARE_STEP_IN);
2951 return result;
2952}
2953
2954
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002955Code::ExtraICState Code::extra_ic_state() {
2956 ASSERT(is_inline_cache_stub());
2957 return ExtractExtraICStateFromFlags(flags());
2958}
2959
2960
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002961PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002962 return ExtractTypeFromFlags(flags());
2963}
2964
2965
2966int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002967 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002968 return ExtractArgumentsCountFromFlags(flags());
2969}
2970
2971
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002972int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002973 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002974 kind() == UNARY_OP_IC ||
2975 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002976 kind() == COMPARE_IC ||
2977 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002978 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002979}
2980
2981
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002982void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002983 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002984 kind() == UNARY_OP_IC ||
2985 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002986 kind() == COMPARE_IC ||
2987 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002988 ASSERT(0 <= major && major < 256);
2989 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002990}
2991
2992
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002993bool Code::is_pregenerated() {
2994 return kind() == STUB && IsPregeneratedField::decode(flags());
2995}
2996
2997
2998void Code::set_is_pregenerated(bool value) {
2999 ASSERT(kind() == STUB);
3000 Flags f = flags();
3001 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3002 set_flags(f);
3003}
3004
3005
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003006bool Code::optimizable() {
3007 ASSERT(kind() == FUNCTION);
3008 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3009}
3010
3011
3012void Code::set_optimizable(bool value) {
3013 ASSERT(kind() == FUNCTION);
3014 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3015}
3016
3017
3018bool Code::has_deoptimization_support() {
3019 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00003020 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3021 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003022}
3023
3024
3025void Code::set_has_deoptimization_support(bool value) {
3026 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00003027 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3028 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3029 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3030}
3031
3032
3033bool Code::has_debug_break_slots() {
3034 ASSERT(kind() == FUNCTION);
3035 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3036 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3037}
3038
3039
3040void Code::set_has_debug_break_slots(bool value) {
3041 ASSERT(kind() == FUNCTION);
3042 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3043 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3044 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003045}
3046
3047
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003048bool Code::is_compiled_optimizable() {
3049 ASSERT(kind() == FUNCTION);
3050 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3051 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3052}
3053
3054
3055void Code::set_compiled_optimizable(bool value) {
3056 ASSERT(kind() == FUNCTION);
3057 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3058 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3059 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3060}
3061
3062
yangguo@chromium.orga7d3df92012-02-27 11:46:55 +00003063bool Code::has_self_optimization_header() {
3064 ASSERT(kind() == FUNCTION);
3065 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3066 return FullCodeFlagsHasSelfOptimizationHeader::decode(flags);
3067}
3068
3069
3070void Code::set_self_optimization_header(bool value) {
3071 ASSERT(kind() == FUNCTION);
3072 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3073 flags = FullCodeFlagsHasSelfOptimizationHeader::update(flags, value);
3074 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3075}
3076
3077
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003078int Code::allow_osr_at_loop_nesting_level() {
3079 ASSERT(kind() == FUNCTION);
3080 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3081}
3082
3083
3084void Code::set_allow_osr_at_loop_nesting_level(int level) {
3085 ASSERT(kind() == FUNCTION);
3086 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3087 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3088}
3089
3090
3091unsigned Code::stack_slots() {
3092 ASSERT(kind() == OPTIMIZED_FUNCTION);
3093 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3094}
3095
3096
3097void Code::set_stack_slots(unsigned slots) {
3098 ASSERT(kind() == OPTIMIZED_FUNCTION);
3099 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3100}
3101
3102
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003103unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003104 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003105 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003106}
3107
3108
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003109void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003110 ASSERT(kind() == OPTIMIZED_FUNCTION);
3111 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003112 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003113}
3114
3115
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003116unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003117 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003118 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003119}
3120
3121
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003122void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003123 ASSERT(kind() == FUNCTION);
3124 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003125 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003126}
3127
3128
3129CheckType Code::check_type() {
3130 ASSERT(is_call_stub() || is_keyed_call_stub());
3131 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3132 return static_cast<CheckType>(type);
3133}
3134
3135
3136void Code::set_check_type(CheckType value) {
3137 ASSERT(is_call_stub() || is_keyed_call_stub());
3138 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3139}
3140
3141
danno@chromium.org40cb8782011-05-25 07:58:50 +00003142byte Code::unary_op_type() {
3143 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003144 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3145}
3146
3147
danno@chromium.org40cb8782011-05-25 07:58:50 +00003148void Code::set_unary_op_type(byte value) {
3149 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003150 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3151}
3152
3153
danno@chromium.org40cb8782011-05-25 07:58:50 +00003154byte Code::binary_op_type() {
3155 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003156 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3157}
3158
3159
danno@chromium.org40cb8782011-05-25 07:58:50 +00003160void Code::set_binary_op_type(byte value) {
3161 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003162 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3163}
3164
3165
danno@chromium.org40cb8782011-05-25 07:58:50 +00003166byte Code::binary_op_result_type() {
3167 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003168 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3169}
3170
3171
danno@chromium.org40cb8782011-05-25 07:58:50 +00003172void Code::set_binary_op_result_type(byte value) {
3173 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003174 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3175}
3176
3177
3178byte Code::compare_state() {
3179 ASSERT(is_compare_ic_stub());
3180 return READ_BYTE_FIELD(this, kCompareStateOffset);
3181}
3182
3183
3184void Code::set_compare_state(byte value) {
3185 ASSERT(is_compare_ic_stub());
3186 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3187}
3188
3189
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003190byte Code::to_boolean_state() {
3191 ASSERT(is_to_boolean_ic_stub());
3192 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3193}
3194
3195
3196void Code::set_to_boolean_state(byte value) {
3197 ASSERT(is_to_boolean_ic_stub());
3198 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3199}
3200
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003201
3202bool Code::has_function_cache() {
3203 ASSERT(kind() == STUB);
3204 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3205}
3206
3207
3208void Code::set_has_function_cache(bool flag) {
3209 ASSERT(kind() == STUB);
3210 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3211}
3212
3213
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003214bool Code::is_inline_cache_stub() {
3215 Kind kind = this->kind();
3216 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3217}
3218
3219
3220Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003221 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003222 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003223 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003224 int argc,
3225 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003226 // Extra IC state is only allowed for call IC stubs or for store IC
3227 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003228 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003229 kind == CALL_IC ||
3230 kind == STORE_IC ||
3231 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003232 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003233 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003234 | ICStateField::encode(ic_state)
3235 | TypeField::encode(type)
3236 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003237 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003238 | CacheHolderField::encode(holder);
3239 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003240}
3241
3242
3243Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3244 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003245 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003246 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003247 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003248 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003249}
3250
3251
3252Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003253 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003254}
3255
3256
kasper.lund7276f142008-07-30 08:49:36 +00003257InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003258 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003259}
3260
3261
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003262Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003263 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003264}
3265
3266
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003267PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003268 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003269}
3270
3271
3272int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003273 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003274}
3275
3276
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003277InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003278 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003279}
3280
3281
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003282Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003283 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003284 return static_cast<Flags>(bits);
3285}
3286
3287
ager@chromium.org8bb60582008-12-11 12:02:20 +00003288Code* Code::GetCodeFromTargetAddress(Address address) {
3289 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3290 // GetCodeFromTargetAddress might be called when marking objects during mark
3291 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3292 // Code::cast. Code::cast does not work when the object's map is
3293 // marked.
3294 Code* result = reinterpret_cast<Code*>(code);
3295 return result;
3296}
3297
3298
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003299Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3300 return HeapObject::
3301 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3302}
3303
3304
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003305Object* Map::prototype() {
3306 return READ_FIELD(this, kPrototypeOffset);
3307}
3308
3309
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003310void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003311 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003312 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003313 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003314}
3315
3316
danno@chromium.org40cb8782011-05-25 07:58:50 +00003317DescriptorArray* Map::instance_descriptors() {
3318 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3319 if (object->IsSmi()) {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003320 return GetHeap()->empty_descriptor_array();
danno@chromium.org40cb8782011-05-25 07:58:50 +00003321 } else {
3322 return DescriptorArray::cast(object);
3323 }
3324}
3325
3326
3327void Map::init_instance_descriptors() {
3328 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3329}
3330
3331
3332void Map::clear_instance_descriptors() {
3333 Object* object = READ_FIELD(this,
3334 kInstanceDescriptorsOrBitField3Offset);
3335 if (!object->IsSmi()) {
3336 WRITE_FIELD(
3337 this,
3338 kInstanceDescriptorsOrBitField3Offset,
3339 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3340 }
3341}
3342
3343
3344void Map::set_instance_descriptors(DescriptorArray* value,
3345 WriteBarrierMode mode) {
3346 Object* object = READ_FIELD(this,
3347 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003348 Heap* heap = GetHeap();
3349 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003350 clear_instance_descriptors();
3351 return;
3352 } else {
3353 if (object->IsSmi()) {
3354 value->set_bit_field3_storage(Smi::cast(object)->value());
3355 } else {
3356 value->set_bit_field3_storage(
3357 DescriptorArray::cast(object)->bit_field3_storage());
3358 }
3359 }
3360 ASSERT(!is_shared());
3361 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003362 CONDITIONAL_WRITE_BARRIER(
3363 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003364}
3365
3366
3367int Map::bit_field3() {
3368 Object* object = READ_FIELD(this,
3369 kInstanceDescriptorsOrBitField3Offset);
3370 if (object->IsSmi()) {
3371 return Smi::cast(object)->value();
3372 } else {
3373 return DescriptorArray::cast(object)->bit_field3_storage();
3374 }
3375}
3376
3377
3378void Map::set_bit_field3(int value) {
3379 ASSERT(Smi::IsValid(value));
3380 Object* object = READ_FIELD(this,
3381 kInstanceDescriptorsOrBitField3Offset);
3382 if (object->IsSmi()) {
3383 WRITE_FIELD(this,
3384 kInstanceDescriptorsOrBitField3Offset,
3385 Smi::FromInt(value));
3386 } else {
3387 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3388 }
3389}
3390
3391
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003392FixedArray* Map::unchecked_prototype_transitions() {
3393 return reinterpret_cast<FixedArray*>(
3394 READ_FIELD(this, kPrototypeTransitionsOffset));
3395}
3396
3397
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003398ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003399ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003400ACCESSORS(Map, constructor, Object, kConstructorOffset)
3401
3402ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003403ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003404ACCESSORS(JSFunction,
3405 next_function_link,
3406 Object,
3407 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003408
3409ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3410ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003411ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003412
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003413ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003414
3415ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3416ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3417ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3418ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003419ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003420
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003421ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3422ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3423
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003424ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3425ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3426ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3427
3428ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3429ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3430ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3431ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3432ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3433ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3434
3435ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3436ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3437
3438ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3439ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3440
3441ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3442ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003443ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3444 kPropertyAccessorsOffset)
3445ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3446 kPrototypeTemplateOffset)
3447ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3448ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3449 kNamedPropertyHandlerOffset)
3450ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3451 kIndexedPropertyHandlerOffset)
3452ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3453 kInstanceTemplateOffset)
3454ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3455ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003456ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3457 kInstanceCallHandlerOffset)
3458ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3459 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003460ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003461
3462ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003463ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3464 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003465
3466ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3467ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3468
3469ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3470
3471ACCESSORS(Script, source, Object, kSourceOffset)
3472ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003473ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003474ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
3475ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003476ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003477ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003478ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003479ACCESSORS_TO_SMI(Script, type, kTypeOffset)
3480ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
3481ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003482ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003483ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003484ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
3485 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003486
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003487#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003488ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3489ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3490ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3491ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3492
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003493ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
3494ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
3495ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003496ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003497#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003498
3499ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003500ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3501ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003502ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3503 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003504ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003505ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3506ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003507ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003508ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3509 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003510
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00003511SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset)
3512
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003513BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3514 kHiddenPrototypeBit)
3515BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3516BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3517 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003518BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3519 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003520BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3521 kIsExpressionBit)
3522BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3523 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003524BOOL_GETTER(SharedFunctionInfo,
3525 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003526 has_only_simple_this_property_assignments,
3527 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003528BOOL_ACCESSORS(SharedFunctionInfo,
3529 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003530 allows_lazy_compilation,
3531 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003532BOOL_ACCESSORS(SharedFunctionInfo,
3533 compiler_hints,
3534 uses_arguments,
3535 kUsesArguments)
3536BOOL_ACCESSORS(SharedFunctionInfo,
3537 compiler_hints,
3538 has_duplicate_parameters,
3539 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003540
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003541
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003542#if V8_HOST_ARCH_32_BIT
3543SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3544SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003545 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003546SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003547 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003548SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3549SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003550 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003551SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3552SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003553 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003554SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003555 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003556SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003557 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003558SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003559SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3560SMI_ACCESSORS(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003561#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003562
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003563#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003564 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003565 int holder::name() { \
3566 int value = READ_INT_FIELD(this, offset); \
3567 ASSERT(kHeapObjectTag == 1); \
3568 ASSERT((value & kHeapObjectTag) == 0); \
3569 return value >> 1; \
3570 } \
3571 void holder::set_##name(int value) { \
3572 ASSERT(kHeapObjectTag == 1); \
3573 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3574 (value & 0xC0000000) == 0x000000000); \
3575 WRITE_INT_FIELD(this, \
3576 offset, \
3577 (value << 1) & ~kHeapObjectTag); \
3578 }
3579
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003580#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3581 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003582 INT_ACCESSORS(holder, name, offset)
3583
3584
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003585PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003586PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3587 formal_parameter_count,
3588 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003589
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003590PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3591 expected_nof_properties,
3592 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003593PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3594
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003595PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3596PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3597 start_position_and_type,
3598 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003599
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003600PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3601 function_token_position,
3602 kFunctionTokenPositionOffset)
3603PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3604 compiler_hints,
3605 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003606
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003607PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3608 this_property_assignments_count,
3609 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003610PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003611
3612PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3613PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003614#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003615
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003616
3617int SharedFunctionInfo::construction_count() {
3618 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3619}
3620
3621
3622void SharedFunctionInfo::set_construction_count(int value) {
3623 ASSERT(0 <= value && value < 256);
3624 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3625}
3626
3627
whesse@chromium.org7b260152011-06-20 15:33:18 +00003628BOOL_ACCESSORS(SharedFunctionInfo,
3629 compiler_hints,
3630 live_objects_may_exist,
3631 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003632
3633
3634bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003635 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003636}
3637
3638
whesse@chromium.org7b260152011-06-20 15:33:18 +00003639BOOL_GETTER(SharedFunctionInfo,
3640 compiler_hints,
3641 optimization_disabled,
3642 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003643
3644
3645void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3646 set_compiler_hints(BooleanBit::set(compiler_hints(),
3647 kOptimizationDisabled,
3648 disable));
3649 // If disabling optimizations we reflect that in the code object so
3650 // it will not be counted as optimizable code.
3651 if ((code()->kind() == Code::FUNCTION) && disable) {
3652 code()->set_optimizable(false);
3653 }
3654}
3655
3656
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003657LanguageMode SharedFunctionInfo::language_mode() {
3658 int hints = compiler_hints();
3659 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3660 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3661 return EXTENDED_MODE;
3662 }
3663 return BooleanBit::get(hints, kStrictModeFunction)
3664 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003665}
3666
3667
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003668void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3669 // We only allow language mode transitions that go set the same language mode
3670 // again or go up in the chain:
3671 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3672 ASSERT(this->language_mode() == CLASSIC_MODE ||
3673 this->language_mode() == language_mode ||
3674 language_mode == EXTENDED_MODE);
3675 int hints = compiler_hints();
3676 hints = BooleanBit::set(
3677 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3678 hints = BooleanBit::set(
3679 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3680 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003681}
3682
3683
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003684bool SharedFunctionInfo::is_classic_mode() {
3685 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3686}
3687
3688BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3689 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003690BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3691BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3692 name_should_print_as_anonymous,
3693 kNameShouldPrintAsAnonymous)
3694BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3695BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00003696BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
3697BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
3698 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003699BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003700
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003701ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3702ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3703
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003704ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3705
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003706bool Script::HasValidSource() {
3707 Object* src = this->source();
3708 if (!src->IsString()) return true;
3709 String* src_str = String::cast(src);
3710 if (!StringShape(src_str).IsExternal()) return true;
3711 if (src_str->IsAsciiRepresentation()) {
3712 return ExternalAsciiString::cast(src)->resource() != NULL;
3713 } else if (src_str->IsTwoByteRepresentation()) {
3714 return ExternalTwoByteString::cast(src)->resource() != NULL;
3715 }
3716 return true;
3717}
3718
3719
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003720void SharedFunctionInfo::DontAdaptArguments() {
3721 ASSERT(code()->kind() == Code::BUILTIN);
3722 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3723}
3724
3725
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003726int SharedFunctionInfo::start_position() {
3727 return start_position_and_type() >> kStartPositionShift;
3728}
3729
3730
3731void SharedFunctionInfo::set_start_position(int start_position) {
3732 set_start_position_and_type((start_position << kStartPositionShift)
3733 | (start_position_and_type() & ~kStartPositionMask));
3734}
3735
3736
3737Code* SharedFunctionInfo::code() {
3738 return Code::cast(READ_FIELD(this, kCodeOffset));
3739}
3740
3741
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003742Code* SharedFunctionInfo::unchecked_code() {
3743 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3744}
3745
3746
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003747void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003748 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003749 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003750}
3751
3752
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003753ScopeInfo* SharedFunctionInfo::scope_info() {
3754 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003755}
3756
3757
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003758void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003759 WriteBarrierMode mode) {
3760 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003761 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3762 this,
3763 kScopeInfoOffset,
3764 reinterpret_cast<Object*>(value),
3765 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003766}
3767
3768
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003769bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003770 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003771 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003772}
3773
3774
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003775bool SharedFunctionInfo::IsApiFunction() {
3776 return function_data()->IsFunctionTemplateInfo();
3777}
3778
3779
3780FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3781 ASSERT(IsApiFunction());
3782 return FunctionTemplateInfo::cast(function_data());
3783}
3784
3785
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003786bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003787 return function_data()->IsSmi();
3788}
3789
3790
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003791BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3792 ASSERT(HasBuiltinFunctionId());
3793 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003794}
3795
3796
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003797int SharedFunctionInfo::code_age() {
3798 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3799}
3800
3801
3802void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00003803 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3804 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003805}
3806
3807
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003808bool SharedFunctionInfo::has_deoptimization_support() {
3809 Code* code = this->code();
3810 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3811}
3812
3813
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003814bool JSFunction::IsBuiltin() {
3815 return context()->global()->IsJSBuiltinsObject();
3816}
3817
3818
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003819bool JSFunction::NeedsArgumentsAdaption() {
3820 return shared()->formal_parameter_count() !=
3821 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3822}
3823
3824
3825bool JSFunction::IsOptimized() {
3826 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3827}
3828
3829
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003830bool JSFunction::IsOptimizable() {
3831 return code()->kind() == Code::FUNCTION && code()->optimizable();
3832}
3833
3834
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003835bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003836 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003837}
3838
3839
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003840Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003841 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003842}
3843
3844
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003845Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003846 return reinterpret_cast<Code*>(
3847 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003848}
3849
3850
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003851void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003852 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003853 Address entry = value->entry();
3854 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003855 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3856 this,
3857 HeapObject::RawField(this, kCodeEntryOffset),
3858 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003859}
3860
3861
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003862void JSFunction::ReplaceCode(Code* code) {
3863 bool was_optimized = IsOptimized();
3864 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3865
3866 set_code(code);
3867
3868 // Add/remove the function from the list of optimized functions for this
3869 // context based on the state change.
3870 if (!was_optimized && is_optimized) {
3871 context()->global_context()->AddOptimizedFunction(this);
3872 }
3873 if (was_optimized && !is_optimized) {
3874 context()->global_context()->RemoveOptimizedFunction(this);
3875 }
3876}
3877
3878
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003879Context* JSFunction::context() {
3880 return Context::cast(READ_FIELD(this, kContextOffset));
3881}
3882
3883
3884Object* JSFunction::unchecked_context() {
3885 return READ_FIELD(this, kContextOffset);
3886}
3887
3888
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003889SharedFunctionInfo* JSFunction::unchecked_shared() {
3890 return reinterpret_cast<SharedFunctionInfo*>(
3891 READ_FIELD(this, kSharedFunctionInfoOffset));
3892}
3893
3894
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003895void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003896 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003897 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003898 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003899}
3900
3901ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3902 kPrototypeOrInitialMapOffset)
3903
3904
3905Map* JSFunction::initial_map() {
3906 return Map::cast(prototype_or_initial_map());
3907}
3908
3909
3910void JSFunction::set_initial_map(Map* value) {
3911 set_prototype_or_initial_map(value);
3912}
3913
3914
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003915MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
3916 Map* initial_map) {
3917 Context* global_context = context()->global_context();
3918 Object* array_function =
3919 global_context->get(Context::ARRAY_FUNCTION_INDEX);
3920 if (array_function->IsJSFunction() &&
3921 this == JSFunction::cast(array_function)) {
3922 ASSERT(initial_map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
3923
3924 MaybeObject* maybe_map = initial_map->CopyDropTransitions();
3925 Map* new_double_map = NULL;
3926 if (!maybe_map->To<Map>(&new_double_map)) return maybe_map;
3927 new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00003928 maybe_map = initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS,
3929 new_double_map);
3930 if (maybe_map->IsFailure()) return maybe_map;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003931
3932 maybe_map = new_double_map->CopyDropTransitions();
3933 Map* new_object_map = NULL;
3934 if (!maybe_map->To<Map>(&new_object_map)) return maybe_map;
3935 new_object_map->set_elements_kind(FAST_ELEMENTS);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00003936 maybe_map = new_double_map->AddElementsTransition(FAST_ELEMENTS,
3937 new_object_map);
3938 if (maybe_map->IsFailure()) return maybe_map;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003939
3940 global_context->set_smi_js_array_map(initial_map);
3941 global_context->set_double_js_array_map(new_double_map);
3942 global_context->set_object_js_array_map(new_object_map);
3943 }
3944 set_initial_map(initial_map);
3945 return this;
3946}
3947
3948
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003949bool JSFunction::has_initial_map() {
3950 return prototype_or_initial_map()->IsMap();
3951}
3952
3953
3954bool JSFunction::has_instance_prototype() {
3955 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3956}
3957
3958
3959bool JSFunction::has_prototype() {
3960 return map()->has_non_instance_prototype() || has_instance_prototype();
3961}
3962
3963
3964Object* JSFunction::instance_prototype() {
3965 ASSERT(has_instance_prototype());
3966 if (has_initial_map()) return initial_map()->prototype();
3967 // When there is no initial map and the prototype is a JSObject, the
3968 // initial map field is used for the prototype field.
3969 return prototype_or_initial_map();
3970}
3971
3972
3973Object* JSFunction::prototype() {
3974 ASSERT(has_prototype());
3975 // If the function's prototype property has been set to a non-JSObject
3976 // value, that value is stored in the constructor field of the map.
3977 if (map()->has_non_instance_prototype()) return map()->constructor();
3978 return instance_prototype();
3979}
3980
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003981bool JSFunction::should_have_prototype() {
3982 return map()->function_with_prototype();
3983}
3984
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003985
3986bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003987 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003988}
3989
3990
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003991FixedArray* JSFunction::literals() {
3992 ASSERT(!shared()->bound());
3993 return literals_or_bindings();
3994}
3995
3996
3997void JSFunction::set_literals(FixedArray* literals) {
3998 ASSERT(!shared()->bound());
3999 set_literals_or_bindings(literals);
4000}
4001
4002
4003FixedArray* JSFunction::function_bindings() {
4004 ASSERT(shared()->bound());
4005 return literals_or_bindings();
4006}
4007
4008
4009void JSFunction::set_function_bindings(FixedArray* bindings) {
4010 ASSERT(shared()->bound());
4011 // Bound function literal may be initialized to the empty fixed array
4012 // before the bindings are set.
4013 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4014 bindings->map() == GetHeap()->fixed_cow_array_map());
4015 set_literals_or_bindings(bindings);
4016}
4017
4018
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004019int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004020 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004021 return literals()->length();
4022}
4023
4024
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004025Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004026 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004027 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004028}
4029
4030
4031void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4032 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004033 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004034 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004035 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004036}
4037
4038
4039Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004040 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004041 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4042}
4043
4044
4045void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4046 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004047 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004048 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004049 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004050}
4051
4052
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004053ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004054ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004055ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4056ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4057
4058
4059void JSProxy::InitializeBody(int object_size, Object* value) {
4060 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4061 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4062 WRITE_FIELD(this, offset, value);
4063 }
4064}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004065
4066
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004067ACCESSORS(JSSet, table, Object, kTableOffset)
4068ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004069ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4070ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004071
4072
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004073Address Foreign::foreign_address() {
4074 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004075}
4076
4077
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004078void Foreign::set_foreign_address(Address value) {
4079 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004080}
4081
4082
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004083ACCESSORS(JSValue, value, Object, kValueOffset)
4084
4085
4086JSValue* JSValue::cast(Object* obj) {
4087 ASSERT(obj->IsJSValue());
4088 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4089 return reinterpret_cast<JSValue*>(obj);
4090}
4091
4092
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004093ACCESSORS(JSDate, value, Object, kValueOffset)
4094ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4095ACCESSORS(JSDate, year, Object, kYearOffset)
4096ACCESSORS(JSDate, month, Object, kMonthOffset)
4097ACCESSORS(JSDate, day, Object, kDayOffset)
4098ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4099ACCESSORS(JSDate, hour, Object, kHourOffset)
4100ACCESSORS(JSDate, min, Object, kMinOffset)
4101ACCESSORS(JSDate, sec, Object, kSecOffset)
4102
4103
4104JSDate* JSDate::cast(Object* obj) {
4105 ASSERT(obj->IsJSDate());
4106 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4107 return reinterpret_cast<JSDate*>(obj);
4108}
4109
4110
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004111ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4112ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4113ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4114ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4115ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4116SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4117SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4118
4119
4120JSMessageObject* JSMessageObject::cast(Object* obj) {
4121 ASSERT(obj->IsJSMessageObject());
4122 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4123 return reinterpret_cast<JSMessageObject*>(obj);
4124}
4125
4126
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004127INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004128ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004129ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004130ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004131ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004132ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00004133INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004134
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004135byte* Code::instruction_start() {
4136 return FIELD_ADDR(this, kHeaderSize);
4137}
4138
4139
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004140byte* Code::instruction_end() {
4141 return instruction_start() + instruction_size();
4142}
4143
4144
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004145int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004146 return RoundUp(instruction_size(), kObjectAlignment);
4147}
4148
4149
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004150FixedArray* Code::unchecked_deoptimization_data() {
4151 return reinterpret_cast<FixedArray*>(
4152 READ_FIELD(this, kDeoptimizationDataOffset));
4153}
4154
4155
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004156ByteArray* Code::unchecked_relocation_info() {
4157 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004158}
4159
4160
4161byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004162 return unchecked_relocation_info()->GetDataStartAddress();
4163}
4164
4165
4166int Code::relocation_size() {
4167 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004168}
4169
4170
4171byte* Code::entry() {
4172 return instruction_start();
4173}
4174
4175
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004176bool Code::contains(byte* inner_pointer) {
4177 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004178}
4179
4180
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004181ACCESSORS(JSArray, length, Object, kLengthOffset)
4182
4183
ager@chromium.org236ad962008-09-25 09:45:57 +00004184ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004185
4186
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004187JSRegExp::Type JSRegExp::TypeTag() {
4188 Object* data = this->data();
4189 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4190 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4191 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004192}
4193
4194
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004195JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4196 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4197 return static_cast<JSRegExp::Type>(smi->value());
4198}
4199
4200
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004201int JSRegExp::CaptureCount() {
4202 switch (TypeTag()) {
4203 case ATOM:
4204 return 0;
4205 case IRREGEXP:
4206 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4207 default:
4208 UNREACHABLE();
4209 return -1;
4210 }
4211}
4212
4213
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004214JSRegExp::Flags JSRegExp::GetFlags() {
4215 ASSERT(this->data()->IsFixedArray());
4216 Object* data = this->data();
4217 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4218 return Flags(smi->value());
4219}
4220
4221
4222String* JSRegExp::Pattern() {
4223 ASSERT(this->data()->IsFixedArray());
4224 Object* data = this->data();
4225 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4226 return pattern;
4227}
4228
4229
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004230Object* JSRegExp::DataAt(int index) {
4231 ASSERT(TypeTag() != NOT_COMPILED);
4232 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004233}
4234
4235
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004236Object* JSRegExp::DataAtUnchecked(int index) {
4237 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4238 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4239 return READ_FIELD(fa, offset);
4240}
4241
4242
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004243void JSRegExp::SetDataAt(int index, Object* value) {
4244 ASSERT(TypeTag() != NOT_COMPILED);
4245 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4246 FixedArray::cast(data())->set(index, value);
4247}
4248
4249
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004250void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4251 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4252 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4253 if (value->IsSmi()) {
4254 fa->set_unchecked(index, Smi::cast(value));
4255 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004256 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004257 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4258 }
4259}
4260
4261
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004262ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004263 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004264#if DEBUG
4265 FixedArrayBase* fixed_array =
4266 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4267 Map* map = fixed_array->map();
4268 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004269 (map == GetHeap()->fixed_array_map() ||
4270 map == GetHeap()->fixed_cow_array_map())) ||
4271 (kind == FAST_DOUBLE_ELEMENTS &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004272 (fixed_array->IsFixedDoubleArray() ||
4273 fixed_array == GetHeap()->empty_fixed_array())) ||
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004274 (kind == DICTIONARY_ELEMENTS &&
4275 fixed_array->IsFixedArray() &&
4276 fixed_array->IsDictionary()) ||
4277 (kind > DICTIONARY_ELEMENTS));
4278 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4279 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004280#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004281 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004282}
4283
4284
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004285ElementsAccessor* JSObject::GetElementsAccessor() {
4286 return ElementsAccessor::ForKind(GetElementsKind());
4287}
4288
4289
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004290bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004291 return GetElementsKind() == FAST_ELEMENTS;
4292}
4293
4294
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004295bool JSObject::HasFastSmiOnlyElements() {
4296 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4297}
4298
4299
4300bool JSObject::HasFastTypeElements() {
4301 ElementsKind elements_kind = GetElementsKind();
4302 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4303 elements_kind == FAST_ELEMENTS;
4304}
4305
4306
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004307bool JSObject::HasFastDoubleElements() {
4308 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4309}
4310
4311
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004312bool JSObject::HasDictionaryElements() {
4313 return GetElementsKind() == DICTIONARY_ELEMENTS;
4314}
4315
4316
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004317bool JSObject::HasNonStrictArgumentsElements() {
4318 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4319}
4320
4321
ager@chromium.org3811b432009-10-28 14:53:37 +00004322bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004323 HeapObject* array = elements();
4324 ASSERT(array != NULL);
4325 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004326}
4327
4328
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004329#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4330bool JSObject::HasExternal##name##Elements() { \
4331 HeapObject* array = elements(); \
4332 ASSERT(array != NULL); \
4333 if (!array->IsHeapObject()) \
4334 return false; \
4335 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004336}
4337
4338
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004339EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4340EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4341EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4342EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4343 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4344EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4345EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4346 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4347EXTERNAL_ELEMENTS_CHECK(Float,
4348 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004349EXTERNAL_ELEMENTS_CHECK(Double,
4350 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004351EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004352
4353
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004354bool JSObject::HasNamedInterceptor() {
4355 return map()->has_named_interceptor();
4356}
4357
4358
4359bool JSObject::HasIndexedInterceptor() {
4360 return map()->has_indexed_interceptor();
4361}
4362
4363
lrn@chromium.org303ada72010-10-27 09:33:13 +00004364MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004365 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004366 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004367 Isolate* isolate = GetIsolate();
4368 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004369 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004370 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4371 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004372 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4373 return maybe_writable_elems;
4374 }
4375 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004376 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004377 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004378 return writable_elems;
4379}
4380
4381
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004382StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004383 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004384 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004385}
4386
4387
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004388SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004389 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004390 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004391}
4392
4393
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004394bool String::IsHashFieldComputed(uint32_t field) {
4395 return (field & kHashNotComputedMask) == 0;
4396}
4397
4398
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004399bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004400 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004401}
4402
4403
4404uint32_t String::Hash() {
4405 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004406 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004407 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004408 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004409 return ComputeAndSetHash();
4410}
4411
4412
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004413StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004414 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004415 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004416 array_index_(0),
4417 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4418 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004419 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004420 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004421}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004422
4423
4424bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004425 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004426}
4427
4428
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004429void StringHasher::AddCharacter(uint32_t c) {
4430 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4431 AddSurrogatePair(c); // Not inlined.
4432 return;
4433 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004434 // Use the Jenkins one-at-a-time hash function to update the hash
4435 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004436 raw_running_hash_ += c;
4437 raw_running_hash_ += (raw_running_hash_ << 10);
4438 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004439 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004440 if (is_array_index_) {
4441 if (c < '0' || c > '9') {
4442 is_array_index_ = false;
4443 } else {
4444 int d = c - '0';
4445 if (is_first_char_) {
4446 is_first_char_ = false;
4447 if (c == '0' && length_ > 1) {
4448 is_array_index_ = false;
4449 return;
4450 }
4451 }
4452 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4453 is_array_index_ = false;
4454 } else {
4455 array_index_ = array_index_ * 10 + d;
4456 }
4457 }
4458 }
4459}
4460
4461
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004462void StringHasher::AddCharacterNoIndex(uint32_t c) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00004463 ASSERT(!is_array_index());
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004464 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4465 AddSurrogatePairNoIndex(c); // Not inlined.
4466 return;
4467 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004468 raw_running_hash_ += c;
4469 raw_running_hash_ += (raw_running_hash_ << 10);
4470 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4471}
4472
4473
4474uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004475 // Get the calculated raw hash value and do some more bit ops to distribute
4476 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004477 uint32_t result = raw_running_hash_;
4478 result += (result << 3);
4479 result ^= (result >> 11);
4480 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004481 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004482 result = 27;
4483 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004484 return result;
4485}
4486
4487
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004488template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004489uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4490 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004491 if (!hasher.has_trivial_hash()) {
4492 int i;
4493 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4494 hasher.AddCharacter(chars[i]);
4495 }
4496 for (; i < length; i++) {
4497 hasher.AddCharacterNoIndex(chars[i]);
4498 }
4499 }
4500 return hasher.GetHashField();
4501}
4502
4503
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004504bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004505 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004506 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4507 return false;
4508 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004509 return SlowAsArrayIndex(index);
4510}
4511
4512
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004513Object* JSReceiver::GetPrototype() {
4514 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004515}
4516
4517
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004518bool JSReceiver::HasProperty(String* name) {
4519 if (IsJSProxy()) {
4520 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4521 }
4522 return GetPropertyAttribute(name) != ABSENT;
4523}
4524
4525
4526bool JSReceiver::HasLocalProperty(String* name) {
4527 if (IsJSProxy()) {
4528 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4529 }
4530 return GetLocalPropertyAttribute(name) != ABSENT;
4531}
4532
4533
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004534PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004535 return GetPropertyAttributeWithReceiver(this, key);
4536}
4537
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004538// TODO(504): this may be useful in other places too where JSGlobalProxy
4539// is used.
4540Object* JSObject::BypassGlobalProxy() {
4541 if (IsJSGlobalProxy()) {
4542 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004543 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004544 ASSERT(proto->IsJSGlobalObject());
4545 return proto;
4546 }
4547 return this;
4548}
4549
4550
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004551MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4552 return IsJSProxy()
4553 ? JSProxy::cast(this)->GetIdentityHash(flag)
4554 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004555}
4556
4557
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004558bool JSReceiver::HasElement(uint32_t index) {
4559 if (IsJSProxy()) {
4560 return JSProxy::cast(this)->HasElementWithHandler(index);
4561 }
4562 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004563}
4564
4565
4566bool AccessorInfo::all_can_read() {
4567 return BooleanBit::get(flag(), kAllCanReadBit);
4568}
4569
4570
4571void AccessorInfo::set_all_can_read(bool value) {
4572 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4573}
4574
4575
4576bool AccessorInfo::all_can_write() {
4577 return BooleanBit::get(flag(), kAllCanWriteBit);
4578}
4579
4580
4581void AccessorInfo::set_all_can_write(bool value) {
4582 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4583}
4584
4585
ager@chromium.org870a0b62008-11-04 11:43:05 +00004586bool AccessorInfo::prohibits_overwriting() {
4587 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4588}
4589
4590
4591void AccessorInfo::set_prohibits_overwriting(bool value) {
4592 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4593}
4594
4595
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004596PropertyAttributes AccessorInfo::property_attributes() {
4597 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4598}
4599
4600
4601void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004602 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004603}
4604
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004605
4606template<typename Shape, typename Key>
4607void Dictionary<Shape, Key>::SetEntry(int entry,
4608 Object* key,
4609 Object* value) {
4610 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4611}
4612
4613
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004614template<typename Shape, typename Key>
4615void Dictionary<Shape, Key>::SetEntry(int entry,
4616 Object* key,
4617 Object* value,
4618 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004619 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004620 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004621 AssertNoAllocation no_gc;
4622 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004623 FixedArray::set(index, key, mode);
4624 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004625 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004626}
4627
4628
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004629bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4630 ASSERT(other->IsNumber());
4631 return key == static_cast<uint32_t>(other->Number());
4632}
4633
4634
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004635uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
4636 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004637}
4638
4639
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004640uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
4641 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004642 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004643 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004644}
4645
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004646uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
4647 return ComputeIntegerHash(key, seed);
4648}
4649
4650uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
4651 uint32_t seed,
4652 Object* other) {
4653 ASSERT(other->IsNumber());
4654 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
4655}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004656
4657MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4658 return Isolate::Current()->heap()->NumberFromUint32(key);
4659}
4660
4661
4662bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4663 // We know that all entries in a hash table had their hash keys created.
4664 // Use that knowledge to have fast failure.
4665 if (key->Hash() != String::cast(other)->Hash()) return false;
4666 return key->Equals(String::cast(other));
4667}
4668
4669
4670uint32_t StringDictionaryShape::Hash(String* key) {
4671 return key->Hash();
4672}
4673
4674
4675uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4676 return String::cast(other)->Hash();
4677}
4678
4679
4680MaybeObject* StringDictionaryShape::AsObject(String* key) {
4681 return key;
4682}
4683
4684
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004685template <int entrysize>
4686bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4687 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004688}
4689
4690
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004691template <int entrysize>
4692uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004693 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4694 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004695}
4696
4697
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004698template <int entrysize>
4699uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4700 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004701 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4702 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004703}
4704
4705
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004706template <int entrysize>
4707MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004708 return key;
4709}
4710
4711
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004712void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004713 // No write barrier is needed since empty_fixed_array is not in new space.
4714 // Please note this function is used during marking:
4715 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00004716 // - IncrementalMarking::Step
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004717 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4718 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004719}
4720
4721
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004722void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004723 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004724 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004725 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4726 if (elts->length() < required_size) {
4727 // Doubling in size would be overkill, but leave some slack to avoid
4728 // constantly growing.
4729 Expand(required_size + (required_size >> 3));
4730 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004731 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004732 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4733 // Expand will allocate a new backing store in new space even if the size
4734 // we asked for isn't larger than what we had before.
4735 Expand(required_size);
4736 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004737}
4738
4739
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004740void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004741 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004742 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4743}
4744
4745
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004746bool JSArray::AllowsSetElementsLength() {
4747 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4748 ASSERT(result == !HasExternalArrayElements());
4749 return result;
4750}
4751
4752
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004753MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4754 MaybeObject* maybe_result = EnsureCanContainElements(
4755 storage, ALLOW_COPIED_DOUBLE_ELEMENTS);
4756 if (maybe_result->IsFailure()) return maybe_result;
4757 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4758 GetElementsKind() == FAST_DOUBLE_ELEMENTS) ||
4759 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4760 ((GetElementsKind() == FAST_ELEMENTS) ||
4761 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS &&
4762 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004763 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004764 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004765 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004766}
4767
4768
lrn@chromium.org303ada72010-10-27 09:33:13 +00004769MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004770 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004771 return GetHeap()->CopyFixedArray(this);
4772}
4773
4774
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004775MaybeObject* FixedDoubleArray::Copy() {
4776 if (length() == 0) return this;
4777 return GetHeap()->CopyFixedDoubleArray(this);
4778}
4779
4780
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004781void TypeFeedbackCells::SetAstId(int index, Smi* id) {
4782 set(1 + index * 2, id);
4783}
4784
4785
4786Smi* TypeFeedbackCells::AstId(int index) {
4787 return Smi::cast(get(1 + index * 2));
4788}
4789
4790
4791void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
4792 set(index * 2, cell);
4793}
4794
4795
4796JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
4797 return JSGlobalPropertyCell::cast(get(index * 2));
4798}
4799
4800
4801Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
4802 return isolate->factory()->the_hole_value();
4803}
4804
4805
4806Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
4807 return isolate->factory()->undefined_value();
4808}
4809
4810
4811Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
4812 return heap->raw_unchecked_the_hole_value();
4813}
4814
4815
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004816SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
4817SMI_ACCESSORS(TypeFeedbackInfo, ic_with_typeinfo_count,
4818 kIcWithTypeinfoCountOffset)
4819ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
4820 kTypeFeedbackCellsOffset)
4821
4822
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00004823SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
4824
4825
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004826Relocatable::Relocatable(Isolate* isolate) {
4827 ASSERT(isolate == Isolate::Current());
4828 isolate_ = isolate;
4829 prev_ = isolate->relocatable_top();
4830 isolate->set_relocatable_top(this);
4831}
4832
4833
4834Relocatable::~Relocatable() {
4835 ASSERT(isolate_ == Isolate::Current());
4836 ASSERT_EQ(isolate_->relocatable_top(), this);
4837 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004838}
4839
4840
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004841int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4842 return map->instance_size();
4843}
4844
4845
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004846void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004847 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004848 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004849}
4850
4851
4852template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004853void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004854 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004855 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004856}
4857
4858
4859void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4860 typedef v8::String::ExternalAsciiStringResource Resource;
4861 v->VisitExternalAsciiString(
4862 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4863}
4864
4865
4866template<typename StaticVisitor>
4867void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4868 typedef v8::String::ExternalAsciiStringResource Resource;
4869 StaticVisitor::VisitExternalAsciiString(
4870 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4871}
4872
4873
4874void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4875 typedef v8::String::ExternalStringResource Resource;
4876 v->VisitExternalTwoByteString(
4877 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4878}
4879
4880
4881template<typename StaticVisitor>
4882void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4883 typedef v8::String::ExternalStringResource Resource;
4884 StaticVisitor::VisitExternalTwoByteString(
4885 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4886}
4887
4888#define SLOT_ADDR(obj, offset) \
4889 reinterpret_cast<Object**>((obj)->address() + offset)
4890
4891template<int start_offset, int end_offset, int size>
4892void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4893 HeapObject* obj,
4894 ObjectVisitor* v) {
4895 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4896}
4897
4898
4899template<int start_offset>
4900void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4901 int object_size,
4902 ObjectVisitor* v) {
4903 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4904}
4905
4906#undef SLOT_ADDR
4907
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004908#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004909#undef CAST_ACCESSOR
4910#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004911#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004912#undef ACCESSORS_TO_SMI
4913#undef SMI_ACCESSORS
4914#undef BOOL_GETTER
4915#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004916#undef FIELD_ADDR
4917#undef READ_FIELD
4918#undef WRITE_FIELD
4919#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004920#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004921#undef READ_DOUBLE_FIELD
4922#undef WRITE_DOUBLE_FIELD
4923#undef READ_INT_FIELD
4924#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004925#undef READ_INTPTR_FIELD
4926#undef WRITE_INTPTR_FIELD
4927#undef READ_UINT32_FIELD
4928#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004929#undef READ_SHORT_FIELD
4930#undef WRITE_SHORT_FIELD
4931#undef READ_BYTE_FIELD
4932#undef WRITE_BYTE_FIELD
4933
4934
4935} } // namespace v8::internal
4936
4937#endif // V8_OBJECTS_INL_H_