blob: 49c8db8db5f4d9c1fa7b51dcad44fbe077c0be6c [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() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003007 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003008 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3009}
3010
3011
3012void Code::set_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003013 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003014 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3015}
3016
3017
3018bool Code::has_deoptimization_support() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003019 ASSERT_EQ(FUNCTION, kind());
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) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003026 ASSERT_EQ(FUNCTION, kind());
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() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003034 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003035 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3036 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3037}
3038
3039
3040void Code::set_has_debug_break_slots(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003041 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003042 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() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003049 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003050 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3051 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3052}
3053
3054
3055void Code::set_compiled_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003056 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003057 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3058 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3059 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3060}
3061
3062
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003063int Code::allow_osr_at_loop_nesting_level() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003064 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003065 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3066}
3067
3068
3069void Code::set_allow_osr_at_loop_nesting_level(int level) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003070 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003071 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3072 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3073}
3074
3075
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003076int Code::profiler_ticks() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003077 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003078 return READ_BYTE_FIELD(this, kProfilerTicksOffset);
3079}
3080
3081
3082void Code::set_profiler_ticks(int ticks) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003083 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003084 ASSERT(ticks < 256);
3085 WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
3086}
3087
3088
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003089unsigned Code::stack_slots() {
3090 ASSERT(kind() == OPTIMIZED_FUNCTION);
3091 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3092}
3093
3094
3095void Code::set_stack_slots(unsigned slots) {
3096 ASSERT(kind() == OPTIMIZED_FUNCTION);
3097 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3098}
3099
3100
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003101unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003102 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003103 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003104}
3105
3106
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003107void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003108 ASSERT(kind() == OPTIMIZED_FUNCTION);
3109 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003110 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003111}
3112
3113
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003114unsigned Code::stack_check_table_offset() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003115 ASSERT_EQ(FUNCTION, kind());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003116 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003117}
3118
3119
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003120void Code::set_stack_check_table_offset(unsigned offset) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003121 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003122 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003123 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003124}
3125
3126
3127CheckType Code::check_type() {
3128 ASSERT(is_call_stub() || is_keyed_call_stub());
3129 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3130 return static_cast<CheckType>(type);
3131}
3132
3133
3134void Code::set_check_type(CheckType value) {
3135 ASSERT(is_call_stub() || is_keyed_call_stub());
3136 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3137}
3138
3139
danno@chromium.org40cb8782011-05-25 07:58:50 +00003140byte Code::unary_op_type() {
3141 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003142 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3143}
3144
3145
danno@chromium.org40cb8782011-05-25 07:58:50 +00003146void Code::set_unary_op_type(byte value) {
3147 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003148 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3149}
3150
3151
danno@chromium.org40cb8782011-05-25 07:58:50 +00003152byte Code::binary_op_type() {
3153 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003154 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3155}
3156
3157
danno@chromium.org40cb8782011-05-25 07:58:50 +00003158void Code::set_binary_op_type(byte value) {
3159 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003160 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3161}
3162
3163
danno@chromium.org40cb8782011-05-25 07:58:50 +00003164byte Code::binary_op_result_type() {
3165 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003166 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3167}
3168
3169
danno@chromium.org40cb8782011-05-25 07:58:50 +00003170void Code::set_binary_op_result_type(byte value) {
3171 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003172 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3173}
3174
3175
3176byte Code::compare_state() {
3177 ASSERT(is_compare_ic_stub());
3178 return READ_BYTE_FIELD(this, kCompareStateOffset);
3179}
3180
3181
3182void Code::set_compare_state(byte value) {
3183 ASSERT(is_compare_ic_stub());
3184 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3185}
3186
3187
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003188byte Code::to_boolean_state() {
3189 ASSERT(is_to_boolean_ic_stub());
3190 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3191}
3192
3193
3194void Code::set_to_boolean_state(byte value) {
3195 ASSERT(is_to_boolean_ic_stub());
3196 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3197}
3198
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003199
3200bool Code::has_function_cache() {
3201 ASSERT(kind() == STUB);
3202 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3203}
3204
3205
3206void Code::set_has_function_cache(bool flag) {
3207 ASSERT(kind() == STUB);
3208 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3209}
3210
3211
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003212bool Code::is_inline_cache_stub() {
3213 Kind kind = this->kind();
3214 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3215}
3216
3217
3218Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003219 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003220 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003221 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003222 int argc,
3223 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003224 // Extra IC state is only allowed for call IC stubs or for store IC
3225 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003226 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003227 kind == CALL_IC ||
3228 kind == STORE_IC ||
3229 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003230 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003231 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003232 | ICStateField::encode(ic_state)
3233 | TypeField::encode(type)
3234 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003235 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003236 | CacheHolderField::encode(holder);
3237 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003238}
3239
3240
3241Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3242 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003243 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003244 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003245 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003246 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003247}
3248
3249
3250Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003251 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003252}
3253
3254
kasper.lund7276f142008-07-30 08:49:36 +00003255InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003256 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003257}
3258
3259
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003260Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003261 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003262}
3263
3264
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003265PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003266 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003267}
3268
3269
3270int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003271 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003272}
3273
3274
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003275InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003276 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003277}
3278
3279
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003280Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003281 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003282 return static_cast<Flags>(bits);
3283}
3284
3285
ager@chromium.org8bb60582008-12-11 12:02:20 +00003286Code* Code::GetCodeFromTargetAddress(Address address) {
3287 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3288 // GetCodeFromTargetAddress might be called when marking objects during mark
3289 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3290 // Code::cast. Code::cast does not work when the object's map is
3291 // marked.
3292 Code* result = reinterpret_cast<Code*>(code);
3293 return result;
3294}
3295
3296
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003297Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3298 return HeapObject::
3299 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3300}
3301
3302
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003303Object* Map::prototype() {
3304 return READ_FIELD(this, kPrototypeOffset);
3305}
3306
3307
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003308void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003309 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003310 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003311 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003312}
3313
3314
danno@chromium.org40cb8782011-05-25 07:58:50 +00003315DescriptorArray* Map::instance_descriptors() {
3316 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3317 if (object->IsSmi()) {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003318 return GetHeap()->empty_descriptor_array();
danno@chromium.org40cb8782011-05-25 07:58:50 +00003319 } else {
3320 return DescriptorArray::cast(object);
3321 }
3322}
3323
3324
3325void Map::init_instance_descriptors() {
3326 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3327}
3328
3329
3330void Map::clear_instance_descriptors() {
3331 Object* object = READ_FIELD(this,
3332 kInstanceDescriptorsOrBitField3Offset);
3333 if (!object->IsSmi()) {
3334 WRITE_FIELD(
3335 this,
3336 kInstanceDescriptorsOrBitField3Offset,
3337 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3338 }
3339}
3340
3341
3342void Map::set_instance_descriptors(DescriptorArray* value,
3343 WriteBarrierMode mode) {
3344 Object* object = READ_FIELD(this,
3345 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003346 Heap* heap = GetHeap();
3347 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003348 clear_instance_descriptors();
3349 return;
3350 } else {
3351 if (object->IsSmi()) {
3352 value->set_bit_field3_storage(Smi::cast(object)->value());
3353 } else {
3354 value->set_bit_field3_storage(
3355 DescriptorArray::cast(object)->bit_field3_storage());
3356 }
3357 }
3358 ASSERT(!is_shared());
3359 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003360 CONDITIONAL_WRITE_BARRIER(
3361 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003362}
3363
3364
3365int Map::bit_field3() {
3366 Object* object = READ_FIELD(this,
3367 kInstanceDescriptorsOrBitField3Offset);
3368 if (object->IsSmi()) {
3369 return Smi::cast(object)->value();
3370 } else {
3371 return DescriptorArray::cast(object)->bit_field3_storage();
3372 }
3373}
3374
3375
3376void Map::set_bit_field3(int value) {
3377 ASSERT(Smi::IsValid(value));
3378 Object* object = READ_FIELD(this,
3379 kInstanceDescriptorsOrBitField3Offset);
3380 if (object->IsSmi()) {
3381 WRITE_FIELD(this,
3382 kInstanceDescriptorsOrBitField3Offset,
3383 Smi::FromInt(value));
3384 } else {
3385 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3386 }
3387}
3388
3389
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003390FixedArray* Map::unchecked_prototype_transitions() {
3391 return reinterpret_cast<FixedArray*>(
3392 READ_FIELD(this, kPrototypeTransitionsOffset));
3393}
3394
3395
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003396ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003397ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003398ACCESSORS(Map, constructor, Object, kConstructorOffset)
3399
3400ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003401ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003402ACCESSORS(JSFunction,
3403 next_function_link,
3404 Object,
3405 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003406
3407ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3408ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003409ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003410
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003411ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003412
3413ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3414ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3415ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3416ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003417ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003418
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003419ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3420ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3421
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003422ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3423ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3424ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3425
3426ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3427ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3428ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3429ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3430ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3431ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3432
3433ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3434ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3435
3436ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3437ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3438
3439ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3440ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003441ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3442 kPropertyAccessorsOffset)
3443ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3444 kPrototypeTemplateOffset)
3445ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3446ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3447 kNamedPropertyHandlerOffset)
3448ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3449 kIndexedPropertyHandlerOffset)
3450ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3451 kInstanceTemplateOffset)
3452ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3453ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003454ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3455 kInstanceCallHandlerOffset)
3456ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3457 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003458ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003459
3460ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003461ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3462 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003463
3464ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3465ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3466
3467ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3468
3469ACCESSORS(Script, source, Object, kSourceOffset)
3470ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003471ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003472ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
3473ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003474ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003475ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003476ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003477ACCESSORS_TO_SMI(Script, type, kTypeOffset)
3478ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
3479ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003480ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003481ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003482ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
3483 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003484
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003485#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003486ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3487ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3488ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3489ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3490
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003491ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
3492ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
3493ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003494ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003495#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003496
3497ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003498ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3499ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003500ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3501 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003502ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003503ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3504ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003505ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003506ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3507 kThisPropertyAssignmentsOffset)
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003508SMI_ACCESSORS(SharedFunctionInfo, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003509
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00003510
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003511BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3512 kHiddenPrototypeBit)
3513BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3514BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3515 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003516BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3517 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003518BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3519 kIsExpressionBit)
3520BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3521 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003522BOOL_GETTER(SharedFunctionInfo,
3523 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003524 has_only_simple_this_property_assignments,
3525 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003526BOOL_ACCESSORS(SharedFunctionInfo,
3527 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003528 allows_lazy_compilation,
3529 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003530BOOL_ACCESSORS(SharedFunctionInfo,
3531 compiler_hints,
3532 uses_arguments,
3533 kUsesArguments)
3534BOOL_ACCESSORS(SharedFunctionInfo,
3535 compiler_hints,
3536 has_duplicate_parameters,
3537 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003538
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003539
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003540#if V8_HOST_ARCH_32_BIT
3541SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3542SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003543 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003544SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003545 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003546SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3547SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003548 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003549SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3550SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003551 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003552SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003553 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003554SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003555 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003556SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003557SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3558SMI_ACCESSORS(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003559#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003560
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003561#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003562 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003563 int holder::name() { \
3564 int value = READ_INT_FIELD(this, offset); \
3565 ASSERT(kHeapObjectTag == 1); \
3566 ASSERT((value & kHeapObjectTag) == 0); \
3567 return value >> 1; \
3568 } \
3569 void holder::set_##name(int value) { \
3570 ASSERT(kHeapObjectTag == 1); \
3571 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3572 (value & 0xC0000000) == 0x000000000); \
3573 WRITE_INT_FIELD(this, \
3574 offset, \
3575 (value << 1) & ~kHeapObjectTag); \
3576 }
3577
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003578#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3579 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003580 INT_ACCESSORS(holder, name, offset)
3581
3582
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003583PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003584PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3585 formal_parameter_count,
3586 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003587
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003588PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3589 expected_nof_properties,
3590 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003591PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3592
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003593PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3594PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3595 start_position_and_type,
3596 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003597
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003598PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3599 function_token_position,
3600 kFunctionTokenPositionOffset)
3601PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3602 compiler_hints,
3603 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003604
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003605PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3606 this_property_assignments_count,
3607 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003608PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003609
3610PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3611PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003612#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003613
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003614
3615int SharedFunctionInfo::construction_count() {
3616 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3617}
3618
3619
3620void SharedFunctionInfo::set_construction_count(int value) {
3621 ASSERT(0 <= value && value < 256);
3622 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3623}
3624
3625
whesse@chromium.org7b260152011-06-20 15:33:18 +00003626BOOL_ACCESSORS(SharedFunctionInfo,
3627 compiler_hints,
3628 live_objects_may_exist,
3629 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003630
3631
3632bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003633 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003634}
3635
3636
whesse@chromium.org7b260152011-06-20 15:33:18 +00003637BOOL_GETTER(SharedFunctionInfo,
3638 compiler_hints,
3639 optimization_disabled,
3640 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003641
3642
3643void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3644 set_compiler_hints(BooleanBit::set(compiler_hints(),
3645 kOptimizationDisabled,
3646 disable));
3647 // If disabling optimizations we reflect that in the code object so
3648 // it will not be counted as optimizable code.
3649 if ((code()->kind() == Code::FUNCTION) && disable) {
3650 code()->set_optimizable(false);
3651 }
3652}
3653
3654
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003655LanguageMode SharedFunctionInfo::language_mode() {
3656 int hints = compiler_hints();
3657 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3658 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3659 return EXTENDED_MODE;
3660 }
3661 return BooleanBit::get(hints, kStrictModeFunction)
3662 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003663}
3664
3665
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003666void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3667 // We only allow language mode transitions that go set the same language mode
3668 // again or go up in the chain:
3669 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3670 ASSERT(this->language_mode() == CLASSIC_MODE ||
3671 this->language_mode() == language_mode ||
3672 language_mode == EXTENDED_MODE);
3673 int hints = compiler_hints();
3674 hints = BooleanBit::set(
3675 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3676 hints = BooleanBit::set(
3677 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3678 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003679}
3680
3681
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003682bool SharedFunctionInfo::is_classic_mode() {
3683 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3684}
3685
3686BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3687 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003688BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3689BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3690 name_should_print_as_anonymous,
3691 kNameShouldPrintAsAnonymous)
3692BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3693BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00003694BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
3695BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
3696 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003697BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003698
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003699ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3700ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3701
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003702ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3703
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003704bool Script::HasValidSource() {
3705 Object* src = this->source();
3706 if (!src->IsString()) return true;
3707 String* src_str = String::cast(src);
3708 if (!StringShape(src_str).IsExternal()) return true;
3709 if (src_str->IsAsciiRepresentation()) {
3710 return ExternalAsciiString::cast(src)->resource() != NULL;
3711 } else if (src_str->IsTwoByteRepresentation()) {
3712 return ExternalTwoByteString::cast(src)->resource() != NULL;
3713 }
3714 return true;
3715}
3716
3717
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003718void SharedFunctionInfo::DontAdaptArguments() {
3719 ASSERT(code()->kind() == Code::BUILTIN);
3720 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3721}
3722
3723
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003724int SharedFunctionInfo::start_position() {
3725 return start_position_and_type() >> kStartPositionShift;
3726}
3727
3728
3729void SharedFunctionInfo::set_start_position(int start_position) {
3730 set_start_position_and_type((start_position << kStartPositionShift)
3731 | (start_position_and_type() & ~kStartPositionMask));
3732}
3733
3734
3735Code* SharedFunctionInfo::code() {
3736 return Code::cast(READ_FIELD(this, kCodeOffset));
3737}
3738
3739
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003740Code* SharedFunctionInfo::unchecked_code() {
3741 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3742}
3743
3744
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003745void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003746 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003747 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003748}
3749
3750
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003751ScopeInfo* SharedFunctionInfo::scope_info() {
3752 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003753}
3754
3755
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003756void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003757 WriteBarrierMode mode) {
3758 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003759 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3760 this,
3761 kScopeInfoOffset,
3762 reinterpret_cast<Object*>(value),
3763 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003764}
3765
3766
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003767bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003768 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003769 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003770}
3771
3772
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003773bool SharedFunctionInfo::IsApiFunction() {
3774 return function_data()->IsFunctionTemplateInfo();
3775}
3776
3777
3778FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3779 ASSERT(IsApiFunction());
3780 return FunctionTemplateInfo::cast(function_data());
3781}
3782
3783
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003784bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003785 return function_data()->IsSmi();
3786}
3787
3788
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003789BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3790 ASSERT(HasBuiltinFunctionId());
3791 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003792}
3793
3794
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003795int SharedFunctionInfo::code_age() {
3796 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3797}
3798
3799
3800void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00003801 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3802 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003803}
3804
3805
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003806bool SharedFunctionInfo::has_deoptimization_support() {
3807 Code* code = this->code();
3808 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3809}
3810
3811
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003812bool JSFunction::IsBuiltin() {
3813 return context()->global()->IsJSBuiltinsObject();
3814}
3815
3816
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003817bool JSFunction::NeedsArgumentsAdaption() {
3818 return shared()->formal_parameter_count() !=
3819 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3820}
3821
3822
3823bool JSFunction::IsOptimized() {
3824 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3825}
3826
3827
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003828bool JSFunction::IsOptimizable() {
3829 return code()->kind() == Code::FUNCTION && code()->optimizable();
3830}
3831
3832
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003833bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003834 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003835}
3836
3837
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003838Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003839 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003840}
3841
3842
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003843Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003844 return reinterpret_cast<Code*>(
3845 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003846}
3847
3848
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003849void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003850 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003851 Address entry = value->entry();
3852 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003853 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3854 this,
3855 HeapObject::RawField(this, kCodeEntryOffset),
3856 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003857}
3858
3859
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003860void JSFunction::ReplaceCode(Code* code) {
3861 bool was_optimized = IsOptimized();
3862 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3863
3864 set_code(code);
3865
3866 // Add/remove the function from the list of optimized functions for this
3867 // context based on the state change.
3868 if (!was_optimized && is_optimized) {
3869 context()->global_context()->AddOptimizedFunction(this);
3870 }
3871 if (was_optimized && !is_optimized) {
3872 context()->global_context()->RemoveOptimizedFunction(this);
3873 }
3874}
3875
3876
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003877Context* JSFunction::context() {
3878 return Context::cast(READ_FIELD(this, kContextOffset));
3879}
3880
3881
3882Object* JSFunction::unchecked_context() {
3883 return READ_FIELD(this, kContextOffset);
3884}
3885
3886
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003887SharedFunctionInfo* JSFunction::unchecked_shared() {
3888 return reinterpret_cast<SharedFunctionInfo*>(
3889 READ_FIELD(this, kSharedFunctionInfoOffset));
3890}
3891
3892
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003893void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003894 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003895 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003896 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003897}
3898
3899ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3900 kPrototypeOrInitialMapOffset)
3901
3902
3903Map* JSFunction::initial_map() {
3904 return Map::cast(prototype_or_initial_map());
3905}
3906
3907
3908void JSFunction::set_initial_map(Map* value) {
3909 set_prototype_or_initial_map(value);
3910}
3911
3912
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003913MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
3914 Map* initial_map) {
3915 Context* global_context = context()->global_context();
3916 Object* array_function =
3917 global_context->get(Context::ARRAY_FUNCTION_INDEX);
3918 if (array_function->IsJSFunction() &&
3919 this == JSFunction::cast(array_function)) {
3920 ASSERT(initial_map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
3921
3922 MaybeObject* maybe_map = initial_map->CopyDropTransitions();
3923 Map* new_double_map = NULL;
3924 if (!maybe_map->To<Map>(&new_double_map)) return maybe_map;
3925 new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00003926 maybe_map = initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS,
3927 new_double_map);
3928 if (maybe_map->IsFailure()) return maybe_map;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003929
3930 maybe_map = new_double_map->CopyDropTransitions();
3931 Map* new_object_map = NULL;
3932 if (!maybe_map->To<Map>(&new_object_map)) return maybe_map;
3933 new_object_map->set_elements_kind(FAST_ELEMENTS);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00003934 maybe_map = new_double_map->AddElementsTransition(FAST_ELEMENTS,
3935 new_object_map);
3936 if (maybe_map->IsFailure()) return maybe_map;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003937
3938 global_context->set_smi_js_array_map(initial_map);
3939 global_context->set_double_js_array_map(new_double_map);
3940 global_context->set_object_js_array_map(new_object_map);
3941 }
3942 set_initial_map(initial_map);
3943 return this;
3944}
3945
3946
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003947bool JSFunction::has_initial_map() {
3948 return prototype_or_initial_map()->IsMap();
3949}
3950
3951
3952bool JSFunction::has_instance_prototype() {
3953 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3954}
3955
3956
3957bool JSFunction::has_prototype() {
3958 return map()->has_non_instance_prototype() || has_instance_prototype();
3959}
3960
3961
3962Object* JSFunction::instance_prototype() {
3963 ASSERT(has_instance_prototype());
3964 if (has_initial_map()) return initial_map()->prototype();
3965 // When there is no initial map and the prototype is a JSObject, the
3966 // initial map field is used for the prototype field.
3967 return prototype_or_initial_map();
3968}
3969
3970
3971Object* JSFunction::prototype() {
3972 ASSERT(has_prototype());
3973 // If the function's prototype property has been set to a non-JSObject
3974 // value, that value is stored in the constructor field of the map.
3975 if (map()->has_non_instance_prototype()) return map()->constructor();
3976 return instance_prototype();
3977}
3978
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003979bool JSFunction::should_have_prototype() {
3980 return map()->function_with_prototype();
3981}
3982
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003983
3984bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003985 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003986}
3987
3988
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003989FixedArray* JSFunction::literals() {
3990 ASSERT(!shared()->bound());
3991 return literals_or_bindings();
3992}
3993
3994
3995void JSFunction::set_literals(FixedArray* literals) {
3996 ASSERT(!shared()->bound());
3997 set_literals_or_bindings(literals);
3998}
3999
4000
4001FixedArray* JSFunction::function_bindings() {
4002 ASSERT(shared()->bound());
4003 return literals_or_bindings();
4004}
4005
4006
4007void JSFunction::set_function_bindings(FixedArray* bindings) {
4008 ASSERT(shared()->bound());
4009 // Bound function literal may be initialized to the empty fixed array
4010 // before the bindings are set.
4011 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4012 bindings->map() == GetHeap()->fixed_cow_array_map());
4013 set_literals_or_bindings(bindings);
4014}
4015
4016
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004017int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004018 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004019 return literals()->length();
4020}
4021
4022
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004023Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004024 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004025 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004026}
4027
4028
4029void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4030 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004031 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004032 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004033 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004034}
4035
4036
4037Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004038 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004039 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4040}
4041
4042
4043void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4044 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004045 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004046 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004047 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004048}
4049
4050
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004051ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004052ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004053ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4054ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4055
4056
4057void JSProxy::InitializeBody(int object_size, Object* value) {
4058 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4059 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4060 WRITE_FIELD(this, offset, value);
4061 }
4062}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004063
4064
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004065ACCESSORS(JSSet, table, Object, kTableOffset)
4066ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004067ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4068ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004069
4070
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004071Address Foreign::foreign_address() {
4072 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004073}
4074
4075
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004076void Foreign::set_foreign_address(Address value) {
4077 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004078}
4079
4080
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004081ACCESSORS(JSValue, value, Object, kValueOffset)
4082
4083
4084JSValue* JSValue::cast(Object* obj) {
4085 ASSERT(obj->IsJSValue());
4086 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4087 return reinterpret_cast<JSValue*>(obj);
4088}
4089
4090
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004091ACCESSORS(JSDate, value, Object, kValueOffset)
4092ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4093ACCESSORS(JSDate, year, Object, kYearOffset)
4094ACCESSORS(JSDate, month, Object, kMonthOffset)
4095ACCESSORS(JSDate, day, Object, kDayOffset)
4096ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4097ACCESSORS(JSDate, hour, Object, kHourOffset)
4098ACCESSORS(JSDate, min, Object, kMinOffset)
4099ACCESSORS(JSDate, sec, Object, kSecOffset)
4100
4101
4102JSDate* JSDate::cast(Object* obj) {
4103 ASSERT(obj->IsJSDate());
4104 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4105 return reinterpret_cast<JSDate*>(obj);
4106}
4107
4108
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004109ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4110ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4111ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4112ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4113ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4114SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4115SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4116
4117
4118JSMessageObject* JSMessageObject::cast(Object* obj) {
4119 ASSERT(obj->IsJSMessageObject());
4120 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4121 return reinterpret_cast<JSMessageObject*>(obj);
4122}
4123
4124
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004125INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004126ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004127ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004128ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004129ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004130ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00004131INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004132
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004133byte* Code::instruction_start() {
4134 return FIELD_ADDR(this, kHeaderSize);
4135}
4136
4137
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004138byte* Code::instruction_end() {
4139 return instruction_start() + instruction_size();
4140}
4141
4142
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004143int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004144 return RoundUp(instruction_size(), kObjectAlignment);
4145}
4146
4147
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004148FixedArray* Code::unchecked_deoptimization_data() {
4149 return reinterpret_cast<FixedArray*>(
4150 READ_FIELD(this, kDeoptimizationDataOffset));
4151}
4152
4153
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004154ByteArray* Code::unchecked_relocation_info() {
4155 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004156}
4157
4158
4159byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004160 return unchecked_relocation_info()->GetDataStartAddress();
4161}
4162
4163
4164int Code::relocation_size() {
4165 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004166}
4167
4168
4169byte* Code::entry() {
4170 return instruction_start();
4171}
4172
4173
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004174bool Code::contains(byte* inner_pointer) {
4175 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004176}
4177
4178
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004179ACCESSORS(JSArray, length, Object, kLengthOffset)
4180
4181
ager@chromium.org236ad962008-09-25 09:45:57 +00004182ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004183
4184
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004185JSRegExp::Type JSRegExp::TypeTag() {
4186 Object* data = this->data();
4187 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4188 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4189 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004190}
4191
4192
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004193JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4194 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4195 return static_cast<JSRegExp::Type>(smi->value());
4196}
4197
4198
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004199int JSRegExp::CaptureCount() {
4200 switch (TypeTag()) {
4201 case ATOM:
4202 return 0;
4203 case IRREGEXP:
4204 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4205 default:
4206 UNREACHABLE();
4207 return -1;
4208 }
4209}
4210
4211
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004212JSRegExp::Flags JSRegExp::GetFlags() {
4213 ASSERT(this->data()->IsFixedArray());
4214 Object* data = this->data();
4215 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4216 return Flags(smi->value());
4217}
4218
4219
4220String* JSRegExp::Pattern() {
4221 ASSERT(this->data()->IsFixedArray());
4222 Object* data = this->data();
4223 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4224 return pattern;
4225}
4226
4227
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004228Object* JSRegExp::DataAt(int index) {
4229 ASSERT(TypeTag() != NOT_COMPILED);
4230 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004231}
4232
4233
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004234Object* JSRegExp::DataAtUnchecked(int index) {
4235 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4236 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4237 return READ_FIELD(fa, offset);
4238}
4239
4240
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004241void JSRegExp::SetDataAt(int index, Object* value) {
4242 ASSERT(TypeTag() != NOT_COMPILED);
4243 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4244 FixedArray::cast(data())->set(index, value);
4245}
4246
4247
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004248void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4249 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4250 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4251 if (value->IsSmi()) {
4252 fa->set_unchecked(index, Smi::cast(value));
4253 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004254 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004255 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4256 }
4257}
4258
4259
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004260ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004261 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004262#if DEBUG
4263 FixedArrayBase* fixed_array =
4264 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4265 Map* map = fixed_array->map();
4266 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004267 (map == GetHeap()->fixed_array_map() ||
4268 map == GetHeap()->fixed_cow_array_map())) ||
4269 (kind == FAST_DOUBLE_ELEMENTS &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004270 (fixed_array->IsFixedDoubleArray() ||
4271 fixed_array == GetHeap()->empty_fixed_array())) ||
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004272 (kind == DICTIONARY_ELEMENTS &&
4273 fixed_array->IsFixedArray() &&
4274 fixed_array->IsDictionary()) ||
4275 (kind > DICTIONARY_ELEMENTS));
4276 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4277 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004278#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004279 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004280}
4281
4282
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004283ElementsAccessor* JSObject::GetElementsAccessor() {
4284 return ElementsAccessor::ForKind(GetElementsKind());
4285}
4286
4287
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004288bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004289 return GetElementsKind() == FAST_ELEMENTS;
4290}
4291
4292
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004293bool JSObject::HasFastSmiOnlyElements() {
4294 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4295}
4296
4297
4298bool JSObject::HasFastTypeElements() {
4299 ElementsKind elements_kind = GetElementsKind();
4300 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4301 elements_kind == FAST_ELEMENTS;
4302}
4303
4304
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004305bool JSObject::HasFastDoubleElements() {
4306 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4307}
4308
4309
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004310bool JSObject::HasDictionaryElements() {
4311 return GetElementsKind() == DICTIONARY_ELEMENTS;
4312}
4313
4314
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004315bool JSObject::HasNonStrictArgumentsElements() {
4316 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4317}
4318
4319
ager@chromium.org3811b432009-10-28 14:53:37 +00004320bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004321 HeapObject* array = elements();
4322 ASSERT(array != NULL);
4323 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004324}
4325
4326
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004327#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4328bool JSObject::HasExternal##name##Elements() { \
4329 HeapObject* array = elements(); \
4330 ASSERT(array != NULL); \
4331 if (!array->IsHeapObject()) \
4332 return false; \
4333 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004334}
4335
4336
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004337EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4338EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4339EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4340EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4341 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4342EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4343EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4344 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4345EXTERNAL_ELEMENTS_CHECK(Float,
4346 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004347EXTERNAL_ELEMENTS_CHECK(Double,
4348 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004349EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004350
4351
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004352bool JSObject::HasNamedInterceptor() {
4353 return map()->has_named_interceptor();
4354}
4355
4356
4357bool JSObject::HasIndexedInterceptor() {
4358 return map()->has_indexed_interceptor();
4359}
4360
4361
lrn@chromium.org303ada72010-10-27 09:33:13 +00004362MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004363 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004364 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004365 Isolate* isolate = GetIsolate();
4366 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004367 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004368 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4369 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004370 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4371 return maybe_writable_elems;
4372 }
4373 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004374 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004375 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004376 return writable_elems;
4377}
4378
4379
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004380StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004381 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004382 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004383}
4384
4385
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004386SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004387 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004388 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004389}
4390
4391
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004392bool String::IsHashFieldComputed(uint32_t field) {
4393 return (field & kHashNotComputedMask) == 0;
4394}
4395
4396
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004397bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004398 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004399}
4400
4401
4402uint32_t String::Hash() {
4403 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004404 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004405 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004406 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004407 return ComputeAndSetHash();
4408}
4409
4410
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004411StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004412 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004413 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004414 array_index_(0),
4415 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4416 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004417 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004418 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004419}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004420
4421
4422bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004423 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004424}
4425
4426
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004427void StringHasher::AddCharacter(uint32_t c) {
4428 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4429 AddSurrogatePair(c); // Not inlined.
4430 return;
4431 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004432 // Use the Jenkins one-at-a-time hash function to update the hash
4433 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004434 raw_running_hash_ += c;
4435 raw_running_hash_ += (raw_running_hash_ << 10);
4436 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004437 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004438 if (is_array_index_) {
4439 if (c < '0' || c > '9') {
4440 is_array_index_ = false;
4441 } else {
4442 int d = c - '0';
4443 if (is_first_char_) {
4444 is_first_char_ = false;
4445 if (c == '0' && length_ > 1) {
4446 is_array_index_ = false;
4447 return;
4448 }
4449 }
4450 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4451 is_array_index_ = false;
4452 } else {
4453 array_index_ = array_index_ * 10 + d;
4454 }
4455 }
4456 }
4457}
4458
4459
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004460void StringHasher::AddCharacterNoIndex(uint32_t c) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00004461 ASSERT(!is_array_index());
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004462 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4463 AddSurrogatePairNoIndex(c); // Not inlined.
4464 return;
4465 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004466 raw_running_hash_ += c;
4467 raw_running_hash_ += (raw_running_hash_ << 10);
4468 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4469}
4470
4471
4472uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004473 // Get the calculated raw hash value and do some more bit ops to distribute
4474 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004475 uint32_t result = raw_running_hash_;
4476 result += (result << 3);
4477 result ^= (result >> 11);
4478 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004479 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004480 result = 27;
4481 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004482 return result;
4483}
4484
4485
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004486template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004487uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4488 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004489 if (!hasher.has_trivial_hash()) {
4490 int i;
4491 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4492 hasher.AddCharacter(chars[i]);
4493 }
4494 for (; i < length; i++) {
4495 hasher.AddCharacterNoIndex(chars[i]);
4496 }
4497 }
4498 return hasher.GetHashField();
4499}
4500
4501
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004502bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004503 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004504 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4505 return false;
4506 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004507 return SlowAsArrayIndex(index);
4508}
4509
4510
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004511Object* JSReceiver::GetPrototype() {
4512 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004513}
4514
4515
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004516bool JSReceiver::HasProperty(String* name) {
4517 if (IsJSProxy()) {
4518 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4519 }
4520 return GetPropertyAttribute(name) != ABSENT;
4521}
4522
4523
4524bool JSReceiver::HasLocalProperty(String* name) {
4525 if (IsJSProxy()) {
4526 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4527 }
4528 return GetLocalPropertyAttribute(name) != ABSENT;
4529}
4530
4531
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004532PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004533 return GetPropertyAttributeWithReceiver(this, key);
4534}
4535
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004536// TODO(504): this may be useful in other places too where JSGlobalProxy
4537// is used.
4538Object* JSObject::BypassGlobalProxy() {
4539 if (IsJSGlobalProxy()) {
4540 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004541 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004542 ASSERT(proto->IsJSGlobalObject());
4543 return proto;
4544 }
4545 return this;
4546}
4547
4548
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004549MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4550 return IsJSProxy()
4551 ? JSProxy::cast(this)->GetIdentityHash(flag)
4552 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004553}
4554
4555
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004556bool JSReceiver::HasElement(uint32_t index) {
4557 if (IsJSProxy()) {
4558 return JSProxy::cast(this)->HasElementWithHandler(index);
4559 }
4560 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004561}
4562
4563
4564bool AccessorInfo::all_can_read() {
4565 return BooleanBit::get(flag(), kAllCanReadBit);
4566}
4567
4568
4569void AccessorInfo::set_all_can_read(bool value) {
4570 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4571}
4572
4573
4574bool AccessorInfo::all_can_write() {
4575 return BooleanBit::get(flag(), kAllCanWriteBit);
4576}
4577
4578
4579void AccessorInfo::set_all_can_write(bool value) {
4580 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4581}
4582
4583
ager@chromium.org870a0b62008-11-04 11:43:05 +00004584bool AccessorInfo::prohibits_overwriting() {
4585 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4586}
4587
4588
4589void AccessorInfo::set_prohibits_overwriting(bool value) {
4590 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4591}
4592
4593
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004594PropertyAttributes AccessorInfo::property_attributes() {
4595 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4596}
4597
4598
4599void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004600 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004601}
4602
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004603
4604template<typename Shape, typename Key>
4605void Dictionary<Shape, Key>::SetEntry(int entry,
4606 Object* key,
4607 Object* value) {
4608 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4609}
4610
4611
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004612template<typename Shape, typename Key>
4613void Dictionary<Shape, Key>::SetEntry(int entry,
4614 Object* key,
4615 Object* value,
4616 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004617 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004618 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004619 AssertNoAllocation no_gc;
4620 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004621 FixedArray::set(index, key, mode);
4622 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004623 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004624}
4625
4626
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004627bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4628 ASSERT(other->IsNumber());
4629 return key == static_cast<uint32_t>(other->Number());
4630}
4631
4632
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004633uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
4634 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004635}
4636
4637
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004638uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
4639 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004640 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004641 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004642}
4643
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004644uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
4645 return ComputeIntegerHash(key, seed);
4646}
4647
4648uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
4649 uint32_t seed,
4650 Object* other) {
4651 ASSERT(other->IsNumber());
4652 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
4653}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004654
4655MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4656 return Isolate::Current()->heap()->NumberFromUint32(key);
4657}
4658
4659
4660bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4661 // We know that all entries in a hash table had their hash keys created.
4662 // Use that knowledge to have fast failure.
4663 if (key->Hash() != String::cast(other)->Hash()) return false;
4664 return key->Equals(String::cast(other));
4665}
4666
4667
4668uint32_t StringDictionaryShape::Hash(String* key) {
4669 return key->Hash();
4670}
4671
4672
4673uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4674 return String::cast(other)->Hash();
4675}
4676
4677
4678MaybeObject* StringDictionaryShape::AsObject(String* key) {
4679 return key;
4680}
4681
4682
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004683template <int entrysize>
4684bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4685 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004686}
4687
4688
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004689template <int entrysize>
4690uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004691 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4692 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004693}
4694
4695
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004696template <int entrysize>
4697uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4698 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004699 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4700 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004701}
4702
4703
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004704template <int entrysize>
4705MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004706 return key;
4707}
4708
4709
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004710void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004711 // No write barrier is needed since empty_fixed_array is not in new space.
4712 // Please note this function is used during marking:
4713 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00004714 // - IncrementalMarking::Step
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004715 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4716 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004717}
4718
4719
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004720void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004721 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004722 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004723 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4724 if (elts->length() < required_size) {
4725 // Doubling in size would be overkill, but leave some slack to avoid
4726 // constantly growing.
4727 Expand(required_size + (required_size >> 3));
4728 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004729 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004730 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4731 // Expand will allocate a new backing store in new space even if the size
4732 // we asked for isn't larger than what we had before.
4733 Expand(required_size);
4734 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004735}
4736
4737
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004738void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004739 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004740 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4741}
4742
4743
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004744bool JSArray::AllowsSetElementsLength() {
4745 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4746 ASSERT(result == !HasExternalArrayElements());
4747 return result;
4748}
4749
4750
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004751MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4752 MaybeObject* maybe_result = EnsureCanContainElements(
4753 storage, ALLOW_COPIED_DOUBLE_ELEMENTS);
4754 if (maybe_result->IsFailure()) return maybe_result;
4755 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4756 GetElementsKind() == FAST_DOUBLE_ELEMENTS) ||
4757 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4758 ((GetElementsKind() == FAST_ELEMENTS) ||
4759 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS &&
4760 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004761 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004762 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004763 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004764}
4765
4766
lrn@chromium.org303ada72010-10-27 09:33:13 +00004767MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004768 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004769 return GetHeap()->CopyFixedArray(this);
4770}
4771
4772
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004773MaybeObject* FixedDoubleArray::Copy() {
4774 if (length() == 0) return this;
4775 return GetHeap()->CopyFixedDoubleArray(this);
4776}
4777
4778
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004779void TypeFeedbackCells::SetAstId(int index, Smi* id) {
4780 set(1 + index * 2, id);
4781}
4782
4783
4784Smi* TypeFeedbackCells::AstId(int index) {
4785 return Smi::cast(get(1 + index * 2));
4786}
4787
4788
4789void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
4790 set(index * 2, cell);
4791}
4792
4793
4794JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
4795 return JSGlobalPropertyCell::cast(get(index * 2));
4796}
4797
4798
4799Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
4800 return isolate->factory()->the_hole_value();
4801}
4802
4803
4804Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
4805 return isolate->factory()->undefined_value();
4806}
4807
4808
4809Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
4810 return heap->raw_unchecked_the_hole_value();
4811}
4812
4813
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004814SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00004815SMI_ACCESSORS(TypeFeedbackInfo, ic_with_type_info_count,
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004816 kIcWithTypeinfoCountOffset)
4817ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
4818 kTypeFeedbackCellsOffset)
4819
4820
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00004821SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
4822
4823
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004824Relocatable::Relocatable(Isolate* isolate) {
4825 ASSERT(isolate == Isolate::Current());
4826 isolate_ = isolate;
4827 prev_ = isolate->relocatable_top();
4828 isolate->set_relocatable_top(this);
4829}
4830
4831
4832Relocatable::~Relocatable() {
4833 ASSERT(isolate_ == Isolate::Current());
4834 ASSERT_EQ(isolate_->relocatable_top(), this);
4835 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004836}
4837
4838
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004839int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4840 return map->instance_size();
4841}
4842
4843
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004844void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004845 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004846 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004847}
4848
4849
4850template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004851void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004852 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004853 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004854}
4855
4856
4857void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4858 typedef v8::String::ExternalAsciiStringResource Resource;
4859 v->VisitExternalAsciiString(
4860 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4861}
4862
4863
4864template<typename StaticVisitor>
4865void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4866 typedef v8::String::ExternalAsciiStringResource Resource;
4867 StaticVisitor::VisitExternalAsciiString(
4868 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4869}
4870
4871
4872void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4873 typedef v8::String::ExternalStringResource Resource;
4874 v->VisitExternalTwoByteString(
4875 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4876}
4877
4878
4879template<typename StaticVisitor>
4880void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4881 typedef v8::String::ExternalStringResource Resource;
4882 StaticVisitor::VisitExternalTwoByteString(
4883 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4884}
4885
4886#define SLOT_ADDR(obj, offset) \
4887 reinterpret_cast<Object**>((obj)->address() + offset)
4888
4889template<int start_offset, int end_offset, int size>
4890void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4891 HeapObject* obj,
4892 ObjectVisitor* v) {
4893 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4894}
4895
4896
4897template<int start_offset>
4898void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4899 int object_size,
4900 ObjectVisitor* v) {
4901 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4902}
4903
4904#undef SLOT_ADDR
4905
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004906#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004907#undef CAST_ACCESSOR
4908#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004909#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004910#undef ACCESSORS_TO_SMI
4911#undef SMI_ACCESSORS
4912#undef BOOL_GETTER
4913#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004914#undef FIELD_ADDR
4915#undef READ_FIELD
4916#undef WRITE_FIELD
4917#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004918#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004919#undef READ_DOUBLE_FIELD
4920#undef WRITE_DOUBLE_FIELD
4921#undef READ_INT_FIELD
4922#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004923#undef READ_INTPTR_FIELD
4924#undef WRITE_INTPTR_FIELD
4925#undef READ_UINT32_FIELD
4926#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004927#undef READ_SHORT_FIELD
4928#undef WRITE_SHORT_FIELD
4929#undef READ_BYTE_FIELD
4930#undef WRITE_BYTE_FIELD
4931
4932
4933} } // namespace v8::internal
4934
4935#endif // V8_OBJECTS_INL_H_