blob: f27a436120f5b3791ce3b8832f80517377f283e6 [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
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000947#define READ_SHORT_FIELD(p, offset) \
948 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
949
950#define WRITE_SHORT_FIELD(p, offset, value) \
951 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
952
953#define READ_BYTE_FIELD(p, offset) \
954 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
955
956#define WRITE_BYTE_FIELD(p, offset, value) \
957 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
958
959
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000960Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
961 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000962}
963
964
965int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000966 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000967}
968
969
970Smi* Smi::FromInt(int value) {
971 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000972 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000973 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000974 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000975 return reinterpret_cast<Smi*>(tagged_value);
976}
977
978
979Smi* Smi::FromIntptr(intptr_t value) {
980 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000981 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
982 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000983}
984
985
986Failure::Type Failure::type() const {
987 return static_cast<Type>(value() & kFailureTypeTagMask);
988}
989
990
991bool Failure::IsInternalError() const {
992 return type() == INTERNAL_ERROR;
993}
994
995
996bool Failure::IsOutOfMemoryException() const {
997 return type() == OUT_OF_MEMORY_EXCEPTION;
998}
999
1000
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001001AllocationSpace Failure::allocation_space() const {
1002 ASSERT_EQ(RETRY_AFTER_GC, type());
1003 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1004 & kSpaceTagMask);
1005}
1006
1007
1008Failure* Failure::InternalError() {
1009 return Construct(INTERNAL_ERROR);
1010}
1011
1012
1013Failure* Failure::Exception() {
1014 return Construct(EXCEPTION);
1015}
1016
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001017
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001018Failure* Failure::OutOfMemoryException() {
1019 return Construct(OUT_OF_MEMORY_EXCEPTION);
1020}
1021
1022
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001023intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001024 return static_cast<intptr_t>(
1025 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001026}
1027
1028
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001029Failure* Failure::RetryAfterGC() {
1030 return RetryAfterGC(NEW_SPACE);
1031}
1032
1033
1034Failure* Failure::RetryAfterGC(AllocationSpace space) {
1035 ASSERT((space & ~kSpaceTagMask) == 0);
1036 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001037}
1038
1039
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001040Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001041 uintptr_t info =
1042 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001043 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001044 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001045}
1046
1047
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001048bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001049#ifdef DEBUG
1050 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1051#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001052
1053#ifdef V8_TARGET_ARCH_X64
1054 // To be representable as a long smi, the value must be a 32-bit integer.
1055 bool result = (value == static_cast<int32_t>(value));
1056#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001057 // To be representable as an tagged small integer, the two
1058 // most-significant bits of 'value' must be either 00 or 11 due to
1059 // sign-extension. To check this we add 01 to the two
1060 // most-significant bits, and check if the most-significant bit is 0
1061 //
1062 // CAUTION: The original code below:
1063 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1064 // may lead to incorrect results according to the C language spec, and
1065 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1066 // compiler may produce undefined results in case of signed integer
1067 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001068 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001069#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001070 ASSERT(result == in_range);
1071 return result;
1072}
1073
1074
kasper.lund7276f142008-07-30 08:49:36 +00001075MapWord MapWord::FromMap(Map* map) {
1076 return MapWord(reinterpret_cast<uintptr_t>(map));
1077}
1078
1079
1080Map* MapWord::ToMap() {
1081 return reinterpret_cast<Map*>(value_);
1082}
1083
1084
1085bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001086 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001087}
1088
1089
1090MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001091 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1092 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001093}
1094
1095
1096HeapObject* MapWord::ToForwardingAddress() {
1097 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001098 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001099}
1100
1101
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001102#ifdef DEBUG
1103void HeapObject::VerifyObjectField(int offset) {
1104 VerifyPointer(READ_FIELD(this, offset));
1105}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001106
1107void HeapObject::VerifySmiField(int offset) {
1108 ASSERT(READ_FIELD(this, offset)->IsSmi());
1109}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001110#endif
1111
1112
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001113Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001114 Heap* heap =
1115 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1116 ASSERT(heap != NULL);
1117 ASSERT(heap->isolate() == Isolate::Current());
1118 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001119}
1120
1121
1122Isolate* HeapObject::GetIsolate() {
1123 return GetHeap()->isolate();
1124}
1125
1126
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001127Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001128 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001129}
1130
1131
1132void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001133 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001134 if (value != NULL) {
1135 // TODO(1600) We are passing NULL as a slot because maps can never be on
1136 // evacuation candidate.
1137 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1138 }
1139}
1140
1141
1142// Unsafe accessor omitting write barrier.
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001143void HeapObject::set_map_no_write_barrier(Map* value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001144 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001145}
1146
1147
kasper.lund7276f142008-07-30 08:49:36 +00001148MapWord HeapObject::map_word() {
1149 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1150}
1151
1152
1153void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001154 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001155 // here.
1156 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1157}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001158
1159
1160HeapObject* HeapObject::FromAddress(Address address) {
1161 ASSERT_TAG_ALIGNED(address);
1162 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1163}
1164
1165
1166Address HeapObject::address() {
1167 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1168}
1169
1170
1171int HeapObject::Size() {
1172 return SizeFromMap(map());
1173}
1174
1175
1176void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1177 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1178 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1179}
1180
1181
1182void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1183 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1184}
1185
1186
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001187double HeapNumber::value() {
1188 return READ_DOUBLE_FIELD(this, kValueOffset);
1189}
1190
1191
1192void HeapNumber::set_value(double value) {
1193 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1194}
1195
1196
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001197int HeapNumber::get_exponent() {
1198 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1199 kExponentShift) - kExponentBias;
1200}
1201
1202
1203int HeapNumber::get_sign() {
1204 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1205}
1206
1207
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001208ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001209
1210
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001211Object** FixedArray::GetFirstElementAddress() {
1212 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1213}
1214
1215
1216bool FixedArray::ContainsOnlySmisOrHoles() {
1217 Object* the_hole = GetHeap()->the_hole_value();
1218 Object** current = GetFirstElementAddress();
1219 for (int i = 0; i < length(); ++i) {
1220 Object* candidate = *current++;
1221 if (!candidate->IsSmi() && candidate != the_hole) return false;
1222 }
1223 return true;
1224}
1225
1226
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001227FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001228 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001229 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001230}
1231
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001232void JSObject::ValidateSmiOnlyElements() {
1233#if DEBUG
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001234 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001235 Heap* heap = GetHeap();
1236 // Don't use elements, since integrity checks will fail if there
1237 // are filler pointers in the array.
1238 FixedArray* fixed_array =
1239 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
1240 Map* map = fixed_array->map();
1241 // Arrays that have been shifted in place can't be verified.
1242 if (map != heap->raw_unchecked_one_pointer_filler_map() &&
1243 map != heap->raw_unchecked_two_pointer_filler_map() &&
1244 map != heap->free_space_map()) {
1245 for (int i = 0; i < fixed_array->length(); i++) {
1246 Object* current = fixed_array->get(i);
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001247 ASSERT(current->IsSmi() || current->IsTheHole());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001248 }
1249 }
1250 }
1251#endif
1252}
1253
1254
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001255MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001256#if DEBUG
1257 ValidateSmiOnlyElements();
1258#endif
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001259 if ((map()->elements_kind() != FAST_ELEMENTS)) {
1260 return TransitionElementsKind(FAST_ELEMENTS);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001261 }
1262 return this;
1263}
1264
1265
1266MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001267 uint32_t count,
1268 EnsureElementsMode mode) {
1269 ElementsKind current_kind = map()->elements_kind();
1270 ElementsKind target_kind = current_kind;
1271 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
1272 if (current_kind == FAST_ELEMENTS) return this;
1273
1274 Heap* heap = GetHeap();
1275 Object* the_hole = heap->the_hole_value();
1276 Object* heap_number_map = heap->heap_number_map();
1277 for (uint32_t i = 0; i < count; ++i) {
1278 Object* current = *objects++;
1279 if (!current->IsSmi() && current != the_hole) {
1280 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS &&
1281 HeapObject::cast(current)->map() == heap_number_map) {
1282 target_kind = FAST_DOUBLE_ELEMENTS;
1283 } else {
1284 target_kind = FAST_ELEMENTS;
1285 break;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001286 }
1287 }
1288 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001289
1290 if (target_kind != current_kind) {
1291 return TransitionElementsKind(target_kind);
1292 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001293 return this;
1294}
1295
1296
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001297MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
1298 EnsureElementsMode mode) {
1299 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1300 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1301 elements->map() == GetHeap()->fixed_cow_array_map());
1302 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1303 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1304 }
1305 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
1306 return EnsureCanContainElements(objects, elements->length(), mode);
1307 }
1308
1309 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
1310 if (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) {
1311 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1312 }
1313
1314 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001315}
1316
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001317
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001318MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
1319 ElementsKind to_kind) {
1320 Map* current_map = map();
1321 ElementsKind from_kind = current_map->elements_kind();
1322
1323 if (from_kind == to_kind) return current_map;
1324
1325 Context* global_context = isolate->context()->global_context();
1326 if (current_map == global_context->smi_js_array_map()) {
1327 if (to_kind == FAST_ELEMENTS) {
1328 return global_context->object_js_array_map();
1329 } else {
1330 if (to_kind == FAST_DOUBLE_ELEMENTS) {
1331 return global_context->double_js_array_map();
1332 } else {
1333 ASSERT(to_kind == DICTIONARY_ELEMENTS);
1334 }
1335 }
1336 }
1337 return GetElementsTransitionMapSlow(to_kind);
1338}
1339
1340
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001341void JSObject::set_map_and_elements(Map* new_map,
1342 FixedArrayBase* value,
1343 WriteBarrierMode mode) {
1344 ASSERT(value->HasValidElements());
1345#ifdef DEBUG
1346 ValidateSmiOnlyElements();
1347#endif
1348 if (new_map != NULL) {
1349 if (mode == UPDATE_WRITE_BARRIER) {
1350 set_map(new_map);
1351 } else {
1352 ASSERT(mode == SKIP_WRITE_BARRIER);
1353 set_map_no_write_barrier(new_map);
1354 }
1355 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001356 ASSERT((map()->has_fast_elements() ||
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001357 map()->has_fast_smi_only_elements() ||
1358 (value == GetHeap()->empty_fixed_array())) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001359 (value->map() == GetHeap()->fixed_array_map() ||
1360 value->map() == GetHeap()->fixed_cow_array_map()));
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001361 ASSERT((value == GetHeap()->empty_fixed_array()) ||
1362 (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001363 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001364 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001365}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001366
1367
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001368void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1369 set_map_and_elements(NULL, value, mode);
1370}
1371
1372
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001373void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001374 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1375 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001376}
1377
1378
1379void JSObject::initialize_elements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001380 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001381 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1382 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001383}
1384
1385
lrn@chromium.org303ada72010-10-27 09:33:13 +00001386MaybeObject* JSObject::ResetElements() {
1387 Object* obj;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001388 ElementsKind elements_kind = FLAG_smi_only_arrays
1389 ? FAST_SMI_ONLY_ELEMENTS
1390 : FAST_ELEMENTS;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001391 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(),
1392 elements_kind);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001393 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001394 set_map(Map::cast(obj));
1395 initialize_elements();
1396 return this;
1397}
1398
1399
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001400ACCESSORS(Oddball, to_string, String, kToStringOffset)
1401ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1402
1403
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001404byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001405 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001406}
1407
1408
1409void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001410 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001411}
1412
1413
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001414Object* JSGlobalPropertyCell::value() {
1415 return READ_FIELD(this, kValueOffset);
1416}
1417
1418
1419void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1420 // The write barrier is not used for global property cells.
1421 ASSERT(!val->IsJSGlobalPropertyCell());
1422 WRITE_FIELD(this, kValueOffset, val);
1423}
1424
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001425
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001426int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001427 InstanceType type = map()->instance_type();
1428 // Check for the most common kind of JavaScript object before
1429 // falling into the generic switch. This speeds up the internal
1430 // field operations considerably on average.
1431 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1432 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001433 case JS_GLOBAL_PROXY_TYPE:
1434 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001435 case JS_GLOBAL_OBJECT_TYPE:
1436 return JSGlobalObject::kSize;
1437 case JS_BUILTINS_OBJECT_TYPE:
1438 return JSBuiltinsObject::kSize;
1439 case JS_FUNCTION_TYPE:
1440 return JSFunction::kSize;
1441 case JS_VALUE_TYPE:
1442 return JSValue::kSize;
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00001443 case JS_DATE_TYPE:
1444 return JSDate::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001445 case JS_ARRAY_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001446 return JSArray::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001447 case JS_WEAK_MAP_TYPE:
1448 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001449 case JS_REGEXP_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001450 return JSRegExp::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001451 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001452 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001453 case JS_MESSAGE_OBJECT_TYPE:
1454 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001455 default:
1456 UNREACHABLE();
1457 return 0;
1458 }
1459}
1460
1461
1462int JSObject::GetInternalFieldCount() {
1463 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001464 // Make sure to adjust for the number of in-object properties. These
1465 // properties do contribute to the size, but are not internal fields.
1466 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1467 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001468}
1469
1470
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001471int JSObject::GetInternalFieldOffset(int index) {
1472 ASSERT(index < GetInternalFieldCount() && index >= 0);
1473 return GetHeaderSize() + (kPointerSize * index);
1474}
1475
1476
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001477Object* JSObject::GetInternalField(int index) {
1478 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001479 // Internal objects do follow immediately after the header, whereas in-object
1480 // properties are at the end of the object. Therefore there is no need
1481 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001482 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1483}
1484
1485
1486void JSObject::SetInternalField(int index, Object* value) {
1487 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001488 // Internal objects do follow immediately after the header, whereas in-object
1489 // properties are at the end of the object. Therefore there is no need
1490 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001491 int offset = GetHeaderSize() + (kPointerSize * index);
1492 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001493 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001494}
1495
1496
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001497void JSObject::SetInternalField(int index, Smi* value) {
1498 ASSERT(index < GetInternalFieldCount() && index >= 0);
1499 // Internal objects do follow immediately after the header, whereas in-object
1500 // properties are at the end of the object. Therefore there is no need
1501 // to adjust the index here.
1502 int offset = GetHeaderSize() + (kPointerSize * index);
1503 WRITE_FIELD(this, offset, value);
1504}
1505
1506
ager@chromium.org7c537e22008-10-16 08:43:32 +00001507// Access fast-case object properties at index. The use of these routines
1508// is needed to correctly distinguish between properties stored in-object and
1509// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001510Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001511 // Adjust for the number of properties stored in the object.
1512 index -= map()->inobject_properties();
1513 if (index < 0) {
1514 int offset = map()->instance_size() + (index * kPointerSize);
1515 return READ_FIELD(this, offset);
1516 } else {
1517 ASSERT(index < properties()->length());
1518 return properties()->get(index);
1519 }
1520}
1521
1522
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001523Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001524 // Adjust for the number of properties stored in the object.
1525 index -= map()->inobject_properties();
1526 if (index < 0) {
1527 int offset = map()->instance_size() + (index * kPointerSize);
1528 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001529 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001530 } else {
1531 ASSERT(index < properties()->length());
1532 properties()->set(index, value);
1533 }
1534 return value;
1535}
1536
1537
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001538int JSObject::GetInObjectPropertyOffset(int index) {
1539 // Adjust for the number of properties stored in the object.
1540 index -= map()->inobject_properties();
1541 ASSERT(index < 0);
1542 return map()->instance_size() + (index * kPointerSize);
1543}
1544
1545
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001546Object* JSObject::InObjectPropertyAt(int index) {
1547 // Adjust for the number of properties stored in the object.
1548 index -= map()->inobject_properties();
1549 ASSERT(index < 0);
1550 int offset = map()->instance_size() + (index * kPointerSize);
1551 return READ_FIELD(this, offset);
1552}
1553
1554
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001555Object* JSObject::InObjectPropertyAtPut(int index,
1556 Object* value,
1557 WriteBarrierMode mode) {
1558 // Adjust for the number of properties stored in the object.
1559 index -= map()->inobject_properties();
1560 ASSERT(index < 0);
1561 int offset = map()->instance_size() + (index * kPointerSize);
1562 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001563 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001564 return value;
1565}
1566
1567
1568
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001569void JSObject::InitializeBody(Map* map,
1570 Object* pre_allocated_value,
1571 Object* filler_value) {
1572 ASSERT(!filler_value->IsHeapObject() ||
1573 !GetHeap()->InNewSpace(filler_value));
1574 ASSERT(!pre_allocated_value->IsHeapObject() ||
1575 !GetHeap()->InNewSpace(pre_allocated_value));
1576 int size = map->instance_size();
1577 int offset = kHeaderSize;
1578 if (filler_value != pre_allocated_value) {
1579 int pre_allocated = map->pre_allocated_property_fields();
1580 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1581 for (int i = 0; i < pre_allocated; i++) {
1582 WRITE_FIELD(this, offset, pre_allocated_value);
1583 offset += kPointerSize;
1584 }
1585 }
1586 while (offset < size) {
1587 WRITE_FIELD(this, offset, filler_value);
1588 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001589 }
1590}
1591
1592
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001593bool JSObject::HasFastProperties() {
1594 return !properties()->IsDictionary();
1595}
1596
1597
1598int JSObject::MaxFastProperties() {
1599 // Allow extra fast properties if the object has more than
1600 // kMaxFastProperties in-object properties. When this is the case,
1601 // it is very unlikely that the object is being used as a dictionary
1602 // and there is a good chance that allowing more map transitions
1603 // will be worth it.
1604 return Max(map()->inobject_properties(), kMaxFastProperties);
1605}
1606
1607
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001608void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001609 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001610 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001611 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001612 }
1613}
1614
1615
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001616bool Object::ToArrayIndex(uint32_t* index) {
1617 if (IsSmi()) {
1618 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001619 if (value < 0) return false;
1620 *index = value;
1621 return true;
1622 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001623 if (IsHeapNumber()) {
1624 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001625 uint32_t uint_value = static_cast<uint32_t>(value);
1626 if (value == static_cast<double>(uint_value)) {
1627 *index = uint_value;
1628 return true;
1629 }
1630 }
1631 return false;
1632}
1633
1634
1635bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1636 if (!this->IsJSValue()) return false;
1637
1638 JSValue* js_value = JSValue::cast(this);
1639 if (!js_value->value()->IsString()) return false;
1640
1641 String* str = String::cast(js_value->value());
1642 if (index >= (uint32_t)str->length()) return false;
1643
1644 return true;
1645}
1646
1647
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001648FixedArrayBase* FixedArrayBase::cast(Object* object) {
1649 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1650 return reinterpret_cast<FixedArrayBase*>(object);
1651}
1652
1653
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001654Object* FixedArray::get(int index) {
1655 ASSERT(index >= 0 && index < this->length());
1656 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1657}
1658
1659
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001660void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001661 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001662 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001663 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1664 int offset = kHeaderSize + index * kPointerSize;
1665 WRITE_FIELD(this, offset, value);
1666}
1667
1668
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001669void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001670 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001671 ASSERT(index >= 0 && index < this->length());
1672 int offset = kHeaderSize + index * kPointerSize;
1673 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001674 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001675}
1676
1677
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001678inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1679 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1680}
1681
1682
1683inline double FixedDoubleArray::hole_nan_as_double() {
1684 return BitCast<double, uint64_t>(kHoleNanInt64);
1685}
1686
1687
1688inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1689 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1690 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1691 return OS::nan_value();
1692}
1693
1694
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001695double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001696 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1697 map() != HEAP->fixed_array_map());
1698 ASSERT(index >= 0 && index < this->length());
1699 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1700 ASSERT(!is_the_hole_nan(result));
1701 return result;
1702}
1703
1704
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001705MaybeObject* FixedDoubleArray::get(int index) {
1706 if (is_the_hole(index)) {
1707 return GetHeap()->the_hole_value();
1708 } else {
1709 return GetHeap()->NumberFromDouble(get_scalar(index));
1710 }
1711}
1712
1713
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001714void FixedDoubleArray::set(int index, double value) {
1715 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1716 map() != HEAP->fixed_array_map());
1717 int offset = kHeaderSize + index * kDoubleSize;
1718 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1719 WRITE_DOUBLE_FIELD(this, offset, value);
1720}
1721
1722
1723void FixedDoubleArray::set_the_hole(int index) {
1724 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1725 map() != HEAP->fixed_array_map());
1726 int offset = kHeaderSize + index * kDoubleSize;
1727 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1728}
1729
1730
1731bool FixedDoubleArray::is_the_hole(int index) {
1732 int offset = kHeaderSize + index * kDoubleSize;
1733 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1734}
1735
1736
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001737WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001738 Heap* heap = GetHeap();
1739 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1740 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001741 return UPDATE_WRITE_BARRIER;
1742}
1743
1744
1745void FixedArray::set(int index,
1746 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001747 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001748 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001749 ASSERT(index >= 0 && index < this->length());
1750 int offset = kHeaderSize + index * kPointerSize;
1751 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001752 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001753}
1754
1755
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001756void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1757 int index,
1758 Object* value) {
1759 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
1760 ASSERT(index >= 0 && index < array->length());
1761 int offset = kHeaderSize + index * kPointerSize;
1762 WRITE_FIELD(array, offset, value);
1763 Heap* heap = array->GetHeap();
1764 if (heap->InNewSpace(value)) {
1765 heap->RecordWrite(array->address(), offset);
1766 }
1767}
1768
1769
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001770void FixedArray::NoWriteBarrierSet(FixedArray* array,
1771 int index,
1772 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001773 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001774 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001775 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001776 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1777}
1778
1779
1780void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001781 ASSERT(map() != HEAP->fixed_cow_array_map());
1782 set_undefined(GetHeap(), index);
1783}
1784
1785
1786void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001787 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001788 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001789 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001790 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001791}
1792
1793
ager@chromium.org236ad962008-09-25 09:45:57 +00001794void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001795 set_null(GetHeap(), index);
1796}
1797
1798
1799void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001800 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001801 ASSERT(!heap->InNewSpace(heap->null_value()));
1802 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001803}
1804
1805
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001806void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001807 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001808 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001809 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1810 WRITE_FIELD(this,
1811 kHeaderSize + index * kPointerSize,
1812 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001813}
1814
1815
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001816void FixedArray::set_unchecked(int index, Smi* value) {
1817 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1818 int offset = kHeaderSize + index * kPointerSize;
1819 WRITE_FIELD(this, offset, value);
1820}
1821
1822
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001823void FixedArray::set_unchecked(Heap* heap,
1824 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001825 Object* value,
1826 WriteBarrierMode mode) {
1827 int offset = kHeaderSize + index * kPointerSize;
1828 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001829 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001830}
1831
1832
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001833void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001834 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001835 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1836 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001837}
1838
1839
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001840Object** FixedArray::data_start() {
1841 return HeapObject::RawField(this, kHeaderSize);
1842}
1843
1844
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001845bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001846 ASSERT(this->IsSmi() ||
1847 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001848 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001849 return this->IsSmi() || length() <= kFirstIndex;
1850}
1851
1852
1853int DescriptorArray::bit_field3_storage() {
1854 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1855 return Smi::cast(storage)->value();
1856}
1857
1858void DescriptorArray::set_bit_field3_storage(int value) {
1859 ASSERT(!IsEmpty());
1860 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001861}
1862
1863
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001864void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1865 int first,
1866 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001867 Object* tmp = array->get(first);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001868 NoIncrementalWriteBarrierSet(array, first, array->get(second));
1869 NoIncrementalWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001870}
1871
1872
1873int DescriptorArray::Search(String* name) {
1874 SLOW_ASSERT(IsSortedNoDuplicates());
1875
1876 // Check for empty descriptor array.
1877 int nof = number_of_descriptors();
1878 if (nof == 0) return kNotFound;
1879
1880 // Fast case: do linear search for small arrays.
1881 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001882 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001883 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001884 }
1885
1886 // Slow case: perform binary search.
1887 return BinarySearch(name, 0, nof - 1);
1888}
1889
1890
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001891int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001892 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001893 if (number == DescriptorLookupCache::kAbsent) {
1894 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001895 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001896 }
1897 return number;
1898}
1899
1900
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001901String* DescriptorArray::GetKey(int descriptor_number) {
1902 ASSERT(descriptor_number < number_of_descriptors());
1903 return String::cast(get(ToKeyIndex(descriptor_number)));
1904}
1905
1906
1907Object* DescriptorArray::GetValue(int descriptor_number) {
1908 ASSERT(descriptor_number < number_of_descriptors());
1909 return GetContentArray()->get(ToValueIndex(descriptor_number));
1910}
1911
1912
1913Smi* DescriptorArray::GetDetails(int descriptor_number) {
1914 ASSERT(descriptor_number < number_of_descriptors());
1915 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1916}
1917
1918
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001919PropertyType DescriptorArray::GetType(int descriptor_number) {
1920 ASSERT(descriptor_number < number_of_descriptors());
1921 return PropertyDetails(GetDetails(descriptor_number)).type();
1922}
1923
1924
1925int DescriptorArray::GetFieldIndex(int descriptor_number) {
1926 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1927}
1928
1929
1930JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1931 return JSFunction::cast(GetValue(descriptor_number));
1932}
1933
1934
1935Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1936 ASSERT(GetType(descriptor_number) == CALLBACKS);
1937 return GetValue(descriptor_number);
1938}
1939
1940
1941AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1942 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001943 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001944 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001945}
1946
1947
1948bool DescriptorArray::IsProperty(int descriptor_number) {
ulan@chromium.org9a21ec42012-03-06 08:42:24 +00001949 Entry entry(this, descriptor_number);
1950 return IsPropertyDescriptor(&entry);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001951}
1952
1953
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001954bool DescriptorArray::IsTransitionOnly(int descriptor_number) {
1955 switch (GetType(descriptor_number)) {
1956 case MAP_TRANSITION:
1957 case CONSTANT_TRANSITION:
1958 case ELEMENTS_TRANSITION:
1959 return true;
1960 case CALLBACKS: {
1961 Object* value = GetValue(descriptor_number);
1962 if (!value->IsAccessorPair()) return false;
1963 AccessorPair* accessors = AccessorPair::cast(value);
1964 return accessors->getter()->IsMap() && accessors->setter()->IsMap();
1965 }
1966 case NORMAL:
1967 case FIELD:
1968 case CONSTANT_FUNCTION:
1969 case HANDLER:
1970 case INTERCEPTOR:
1971 case NULL_DESCRIPTOR:
1972 return false;
1973 }
1974 UNREACHABLE(); // Keep the compiler happy.
1975 return false;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001976}
1977
1978
1979bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1980 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1981}
1982
1983
1984bool DescriptorArray::IsDontEnum(int descriptor_number) {
1985 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1986}
1987
1988
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001989void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1990 desc->Init(GetKey(descriptor_number),
1991 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001992 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001993}
1994
1995
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001996void DescriptorArray::Set(int descriptor_number,
1997 Descriptor* desc,
1998 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001999 // Range check.
2000 ASSERT(descriptor_number < number_of_descriptors());
2001
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002002 NoIncrementalWriteBarrierSet(this,
2003 ToKeyIndex(descriptor_number),
2004 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002005 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002006 NoIncrementalWriteBarrierSet(content_array,
2007 ToValueIndex(descriptor_number),
2008 desc->GetValue());
2009 NoIncrementalWriteBarrierSet(content_array,
2010 ToDetailsIndex(descriptor_number),
2011 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002012}
2013
2014
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002015void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2016 int first, int second) {
2017 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002018 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002019 NoIncrementalWriteBarrierSwap(content_array,
2020 ToValueIndex(first),
2021 ToValueIndex(second));
2022 NoIncrementalWriteBarrierSwap(content_array,
2023 ToDetailsIndex(first),
2024 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002025}
2026
2027
2028DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
2029 : marking_(array->GetHeap()->incremental_marking()) {
2030 marking_->EnterNoMarkingScope();
2031 if (array->number_of_descriptors() > 0) {
2032 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
2033 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
2034 }
2035}
2036
2037
2038DescriptorArray::WhitenessWitness::~WhitenessWitness() {
2039 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002040}
2041
2042
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002043template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002044int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2045 const int kMinCapacity = 32;
2046 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2047 if (capacity < kMinCapacity) {
2048 capacity = kMinCapacity; // Guarantee min capacity.
2049 }
2050 return capacity;
2051}
2052
2053
2054template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002055int HashTable<Shape, Key>::FindEntry(Key key) {
2056 return FindEntry(GetIsolate(), key);
2057}
2058
2059
2060// Find entry for key otherwise return kNotFound.
2061template<typename Shape, typename Key>
2062int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2063 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002064 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002065 uint32_t count = 1;
2066 // EnsureCapacity will guarantee the hash table is never full.
2067 while (true) {
2068 Object* element = KeyAt(entry);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002069 // Empty entry.
2070 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2071 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002072 Shape::IsMatch(key, element)) return entry;
2073 entry = NextProbe(entry, count++, capacity);
2074 }
2075 return kNotFound;
2076}
2077
2078
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002079bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002080 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002081 if (!max_index_object->IsSmi()) return false;
2082 return 0 !=
2083 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2084}
2085
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002086uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002087 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002088 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002089 if (!max_index_object->IsSmi()) return 0;
2090 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2091 return value >> kRequiresSlowElementsTagSize;
2092}
2093
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002094void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002095 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002096}
2097
2098
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002099// ------------------------------------
2100// Cast operations
2101
2102
2103CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002104CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002105CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002106CAST_ACCESSOR(DeoptimizationInputData)
2107CAST_ACCESSOR(DeoptimizationOutputData)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002108CAST_ACCESSOR(TypeFeedbackCells)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002109CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002110CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002111CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002112CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002113CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002114CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002115CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002116CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002117CAST_ACCESSOR(String)
2118CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002119CAST_ACCESSOR(SeqAsciiString)
2120CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002121CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002122CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002123CAST_ACCESSOR(ExternalString)
2124CAST_ACCESSOR(ExternalAsciiString)
2125CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002126CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002127CAST_ACCESSOR(JSObject)
2128CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002129CAST_ACCESSOR(HeapObject)
2130CAST_ACCESSOR(HeapNumber)
2131CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002132CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002133CAST_ACCESSOR(SharedFunctionInfo)
2134CAST_ACCESSOR(Map)
2135CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002136CAST_ACCESSOR(GlobalObject)
2137CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002138CAST_ACCESSOR(JSGlobalObject)
2139CAST_ACCESSOR(JSBuiltinsObject)
2140CAST_ACCESSOR(Code)
2141CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002142CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002143CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002144CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002145CAST_ACCESSOR(JSSet)
2146CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002147CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002148CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002149CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002150CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002151CAST_ACCESSOR(ExternalArray)
2152CAST_ACCESSOR(ExternalByteArray)
2153CAST_ACCESSOR(ExternalUnsignedByteArray)
2154CAST_ACCESSOR(ExternalShortArray)
2155CAST_ACCESSOR(ExternalUnsignedShortArray)
2156CAST_ACCESSOR(ExternalIntArray)
2157CAST_ACCESSOR(ExternalUnsignedIntArray)
2158CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002159CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002160CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002161CAST_ACCESSOR(Struct)
2162
2163
2164#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2165 STRUCT_LIST(MAKE_STRUCT_CAST)
2166#undef MAKE_STRUCT_CAST
2167
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002168
2169template <typename Shape, typename Key>
2170HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002171 ASSERT(obj->IsHashTable());
2172 return reinterpret_cast<HashTable*>(obj);
2173}
2174
2175
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002176SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002177SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002178
ager@chromium.orgac091b72010-05-05 07:34:42 +00002179SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002180
2181
2182uint32_t String::hash_field() {
2183 return READ_UINT32_FIELD(this, kHashFieldOffset);
2184}
2185
2186
2187void String::set_hash_field(uint32_t value) {
2188 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002189#if V8_HOST_ARCH_64_BIT
2190 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2191#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002192}
2193
2194
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002195bool String::Equals(String* other) {
2196 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002197 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2198 return false;
2199 }
2200 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002201}
2202
2203
lrn@chromium.org303ada72010-10-27 09:33:13 +00002204MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002205 if (!StringShape(this).IsCons()) return this;
2206 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002207 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002208 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002209}
2210
2211
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002212String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002213 MaybeObject* flat = TryFlatten(pretenure);
2214 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002215 if (!flat->ToObject(&successfully_flattened)) return this;
2216 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002217}
2218
2219
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002220uint16_t String::Get(int index) {
2221 ASSERT(index >= 0 && index < length());
2222 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002223 case kSeqStringTag | kAsciiStringTag:
2224 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2225 case kSeqStringTag | kTwoByteStringTag:
2226 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2227 case kConsStringTag | kAsciiStringTag:
2228 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002229 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002230 case kExternalStringTag | kAsciiStringTag:
2231 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2232 case kExternalStringTag | kTwoByteStringTag:
2233 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002234 case kSlicedStringTag | kAsciiStringTag:
2235 case kSlicedStringTag | kTwoByteStringTag:
2236 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002237 default:
2238 break;
2239 }
2240
2241 UNREACHABLE();
2242 return 0;
2243}
2244
2245
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002246void String::Set(int index, uint16_t value) {
2247 ASSERT(index >= 0 && index < length());
2248 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002249
ager@chromium.org5ec48922009-05-05 07:25:34 +00002250 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002251 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2252 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002253}
2254
2255
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002256bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002257 if (!StringShape(this).IsCons()) return true;
2258 return ConsString::cast(this)->second()->length() == 0;
2259}
2260
2261
2262String* String::GetUnderlying() {
2263 // Giving direct access to underlying string only makes sense if the
2264 // wrapping string is already flattened.
2265 ASSERT(this->IsFlat());
2266 ASSERT(StringShape(this).IsIndirect());
2267 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2268 const int kUnderlyingOffset = SlicedString::kParentOffset;
2269 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002270}
2271
2272
ager@chromium.org7c537e22008-10-16 08:43:32 +00002273uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002274 ASSERT(index >= 0 && index < length());
2275 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2276}
2277
2278
ager@chromium.org7c537e22008-10-16 08:43:32 +00002279void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002280 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2281 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2282 static_cast<byte>(value));
2283}
2284
2285
ager@chromium.org7c537e22008-10-16 08:43:32 +00002286Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002287 return FIELD_ADDR(this, kHeaderSize);
2288}
2289
2290
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002291char* SeqAsciiString::GetChars() {
2292 return reinterpret_cast<char*>(GetCharsAddress());
2293}
2294
2295
ager@chromium.org7c537e22008-10-16 08:43:32 +00002296Address SeqTwoByteString::GetCharsAddress() {
2297 return FIELD_ADDR(this, kHeaderSize);
2298}
2299
2300
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002301uc16* SeqTwoByteString::GetChars() {
2302 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2303}
2304
2305
ager@chromium.org7c537e22008-10-16 08:43:32 +00002306uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002307 ASSERT(index >= 0 && index < length());
2308 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2309}
2310
2311
ager@chromium.org7c537e22008-10-16 08:43:32 +00002312void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002313 ASSERT(index >= 0 && index < length());
2314 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2315}
2316
2317
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002318int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002319 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002320}
2321
2322
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002323int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002324 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002325}
2326
2327
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002328String* SlicedString::parent() {
2329 return String::cast(READ_FIELD(this, kParentOffset));
2330}
2331
2332
2333void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002334 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002335 WRITE_FIELD(this, kParentOffset, parent);
2336}
2337
2338
2339SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2340
2341
ager@chromium.org870a0b62008-11-04 11:43:05 +00002342String* ConsString::first() {
2343 return String::cast(READ_FIELD(this, kFirstOffset));
2344}
2345
2346
2347Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002348 return READ_FIELD(this, kFirstOffset);
2349}
2350
2351
ager@chromium.org870a0b62008-11-04 11:43:05 +00002352void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002353 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002354 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002355}
2356
2357
ager@chromium.org870a0b62008-11-04 11:43:05 +00002358String* ConsString::second() {
2359 return String::cast(READ_FIELD(this, kSecondOffset));
2360}
2361
2362
2363Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002364 return READ_FIELD(this, kSecondOffset);
2365}
2366
2367
ager@chromium.org870a0b62008-11-04 11:43:05 +00002368void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002369 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002370 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002371}
2372
2373
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002374bool ExternalString::is_short() {
2375 InstanceType type = map()->instance_type();
2376 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002377}
2378
2379
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002380const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002381 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2382}
2383
2384
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002385void ExternalAsciiString::update_data_cache() {
2386 if (is_short()) return;
2387 const char** data_field =
2388 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2389 *data_field = resource()->data();
2390}
2391
2392
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002393void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002394 const ExternalAsciiString::Resource* resource) {
2395 *reinterpret_cast<const Resource**>(
2396 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002397 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002398}
2399
2400
2401const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002402 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002403}
2404
2405
2406uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2407 ASSERT(index >= 0 && index < length());
2408 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002409}
2410
2411
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002412const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002413 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2414}
2415
2416
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002417void ExternalTwoByteString::update_data_cache() {
2418 if (is_short()) return;
2419 const uint16_t** data_field =
2420 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2421 *data_field = resource()->data();
2422}
2423
2424
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002425void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002426 const ExternalTwoByteString::Resource* resource) {
2427 *reinterpret_cast<const Resource**>(
2428 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002429 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002430}
2431
2432
2433const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002434 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002435}
2436
2437
2438uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2439 ASSERT(index >= 0 && index < length());
2440 return GetChars()[index];
2441}
2442
2443
2444const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2445 unsigned start) {
2446 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002447}
2448
2449
ager@chromium.orgac091b72010-05-05 07:34:42 +00002450void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002451 set_finger_index(kEntriesIndex);
2452 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002453}
2454
2455
2456void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002457 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002458 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002459 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002460 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002461 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002462 MakeZeroSize();
2463}
2464
2465
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002466int JSFunctionResultCache::size() {
2467 return Smi::cast(get(kCacheSizeIndex))->value();
2468}
2469
2470
2471void JSFunctionResultCache::set_size(int size) {
2472 set(kCacheSizeIndex, Smi::FromInt(size));
2473}
2474
2475
2476int JSFunctionResultCache::finger_index() {
2477 return Smi::cast(get(kFingerIndex))->value();
2478}
2479
2480
2481void JSFunctionResultCache::set_finger_index(int finger_index) {
2482 set(kFingerIndex, Smi::FromInt(finger_index));
2483}
2484
2485
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002486byte ByteArray::get(int index) {
2487 ASSERT(index >= 0 && index < this->length());
2488 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2489}
2490
2491
2492void ByteArray::set(int index, byte value) {
2493 ASSERT(index >= 0 && index < this->length());
2494 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2495}
2496
2497
2498int ByteArray::get_int(int index) {
2499 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2500 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2501}
2502
2503
2504ByteArray* ByteArray::FromDataStartAddress(Address address) {
2505 ASSERT_TAG_ALIGNED(address);
2506 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2507}
2508
2509
2510Address ByteArray::GetDataStartAddress() {
2511 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2512}
2513
2514
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002515uint8_t* ExternalPixelArray::external_pixel_pointer() {
2516 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002517}
2518
2519
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002520uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002521 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002522 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002523 return ptr[index];
2524}
2525
2526
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002527MaybeObject* ExternalPixelArray::get(int index) {
2528 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2529}
2530
2531
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002532void ExternalPixelArray::set(int index, uint8_t value) {
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 ptr[index] = value;
2536}
2537
2538
ager@chromium.org3811b432009-10-28 14:53:37 +00002539void* ExternalArray::external_pointer() {
2540 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2541 return reinterpret_cast<void*>(ptr);
2542}
2543
2544
2545void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2546 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2547 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2548}
2549
2550
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002551int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002552 ASSERT((index >= 0) && (index < this->length()));
2553 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2554 return ptr[index];
2555}
2556
2557
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002558MaybeObject* ExternalByteArray::get(int index) {
2559 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2560}
2561
2562
ager@chromium.org3811b432009-10-28 14:53:37 +00002563void ExternalByteArray::set(int index, int8_t value) {
2564 ASSERT((index >= 0) && (index < this->length()));
2565 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2566 ptr[index] = value;
2567}
2568
2569
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002570uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002571 ASSERT((index >= 0) && (index < this->length()));
2572 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2573 return ptr[index];
2574}
2575
2576
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002577MaybeObject* ExternalUnsignedByteArray::get(int index) {
2578 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2579}
2580
2581
ager@chromium.org3811b432009-10-28 14:53:37 +00002582void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2583 ASSERT((index >= 0) && (index < this->length()));
2584 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2585 ptr[index] = value;
2586}
2587
2588
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002589int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002590 ASSERT((index >= 0) && (index < this->length()));
2591 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2592 return ptr[index];
2593}
2594
2595
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002596MaybeObject* ExternalShortArray::get(int index) {
2597 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2598}
2599
2600
ager@chromium.org3811b432009-10-28 14:53:37 +00002601void ExternalShortArray::set(int index, int16_t value) {
2602 ASSERT((index >= 0) && (index < this->length()));
2603 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2604 ptr[index] = value;
2605}
2606
2607
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002608uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002609 ASSERT((index >= 0) && (index < this->length()));
2610 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2611 return ptr[index];
2612}
2613
2614
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002615MaybeObject* ExternalUnsignedShortArray::get(int index) {
2616 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2617}
2618
2619
ager@chromium.org3811b432009-10-28 14:53:37 +00002620void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2621 ASSERT((index >= 0) && (index < this->length()));
2622 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2623 ptr[index] = value;
2624}
2625
2626
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002627int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002628 ASSERT((index >= 0) && (index < this->length()));
2629 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2630 return ptr[index];
2631}
2632
2633
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002634MaybeObject* ExternalIntArray::get(int index) {
2635 return GetHeap()->NumberFromInt32(get_scalar(index));
2636}
2637
2638
ager@chromium.org3811b432009-10-28 14:53:37 +00002639void ExternalIntArray::set(int index, int32_t value) {
2640 ASSERT((index >= 0) && (index < this->length()));
2641 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2642 ptr[index] = value;
2643}
2644
2645
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002646uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002647 ASSERT((index >= 0) && (index < this->length()));
2648 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2649 return ptr[index];
2650}
2651
2652
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002653MaybeObject* ExternalUnsignedIntArray::get(int index) {
2654 return GetHeap()->NumberFromUint32(get_scalar(index));
2655}
2656
2657
ager@chromium.org3811b432009-10-28 14:53:37 +00002658void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2659 ASSERT((index >= 0) && (index < this->length()));
2660 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2661 ptr[index] = value;
2662}
2663
2664
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002665float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002666 ASSERT((index >= 0) && (index < this->length()));
2667 float* ptr = static_cast<float*>(external_pointer());
2668 return ptr[index];
2669}
2670
2671
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002672MaybeObject* ExternalFloatArray::get(int index) {
2673 return GetHeap()->NumberFromDouble(get_scalar(index));
2674}
2675
2676
ager@chromium.org3811b432009-10-28 14:53:37 +00002677void ExternalFloatArray::set(int index, float value) {
2678 ASSERT((index >= 0) && (index < this->length()));
2679 float* ptr = static_cast<float*>(external_pointer());
2680 ptr[index] = value;
2681}
2682
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002683
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002684double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002685 ASSERT((index >= 0) && (index < this->length()));
2686 double* ptr = static_cast<double*>(external_pointer());
2687 return ptr[index];
2688}
2689
2690
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002691MaybeObject* ExternalDoubleArray::get(int index) {
2692 return GetHeap()->NumberFromDouble(get_scalar(index));
2693}
2694
2695
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002696void ExternalDoubleArray::set(int index, double value) {
2697 ASSERT((index >= 0) && (index < this->length()));
2698 double* ptr = static_cast<double*>(external_pointer());
2699 ptr[index] = value;
2700}
2701
2702
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002703int Map::visitor_id() {
2704 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2705}
2706
2707
2708void Map::set_visitor_id(int id) {
2709 ASSERT(0 <= id && id < 256);
2710 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2711}
2712
ager@chromium.org3811b432009-10-28 14:53:37 +00002713
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002714int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002715 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2716}
2717
2718
2719int Map::inobject_properties() {
2720 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002721}
2722
2723
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002724int Map::pre_allocated_property_fields() {
2725 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2726}
2727
2728
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002729int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002730 int instance_size = map->instance_size();
2731 if (instance_size != kVariableSizeSentinel) return instance_size;
2732 // We can ignore the "symbol" bit becase it is only set for symbols
2733 // and implies a string type.
2734 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002735 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002736 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002737 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002738 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002739 if (instance_type == ASCII_STRING_TYPE) {
2740 return SeqAsciiString::SizeFor(
2741 reinterpret_cast<SeqAsciiString*>(this)->length());
2742 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002743 if (instance_type == BYTE_ARRAY_TYPE) {
2744 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2745 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002746 if (instance_type == FREE_SPACE_TYPE) {
2747 return reinterpret_cast<FreeSpace*>(this)->size();
2748 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002749 if (instance_type == STRING_TYPE) {
2750 return SeqTwoByteString::SizeFor(
2751 reinterpret_cast<SeqTwoByteString*>(this)->length());
2752 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002753 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2754 return FixedDoubleArray::SizeFor(
2755 reinterpret_cast<FixedDoubleArray*>(this)->length());
2756 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002757 ASSERT(instance_type == CODE_TYPE);
2758 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002759}
2760
2761
2762void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002763 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002764 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002765 ASSERT(0 <= value && value < 256);
2766 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2767}
2768
2769
ager@chromium.org7c537e22008-10-16 08:43:32 +00002770void Map::set_inobject_properties(int value) {
2771 ASSERT(0 <= value && value < 256);
2772 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2773}
2774
2775
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002776void Map::set_pre_allocated_property_fields(int value) {
2777 ASSERT(0 <= value && value < 256);
2778 WRITE_BYTE_FIELD(this,
2779 kPreAllocatedPropertyFieldsOffset,
2780 static_cast<byte>(value));
2781}
2782
2783
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002784InstanceType Map::instance_type() {
2785 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2786}
2787
2788
2789void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002790 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2791}
2792
2793
2794int Map::unused_property_fields() {
2795 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2796}
2797
2798
2799void Map::set_unused_property_fields(int value) {
2800 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2801}
2802
2803
2804byte Map::bit_field() {
2805 return READ_BYTE_FIELD(this, kBitFieldOffset);
2806}
2807
2808
2809void Map::set_bit_field(byte value) {
2810 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2811}
2812
2813
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002814byte Map::bit_field2() {
2815 return READ_BYTE_FIELD(this, kBitField2Offset);
2816}
2817
2818
2819void Map::set_bit_field2(byte value) {
2820 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2821}
2822
2823
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002824void Map::set_non_instance_prototype(bool value) {
2825 if (value) {
2826 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2827 } else {
2828 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2829 }
2830}
2831
2832
2833bool Map::has_non_instance_prototype() {
2834 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2835}
2836
2837
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002838void Map::set_function_with_prototype(bool value) {
2839 if (value) {
2840 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2841 } else {
2842 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2843 }
2844}
2845
2846
2847bool Map::function_with_prototype() {
2848 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2849}
2850
2851
ager@chromium.org870a0b62008-11-04 11:43:05 +00002852void Map::set_is_access_check_needed(bool access_check_needed) {
2853 if (access_check_needed) {
2854 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2855 } else {
2856 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2857 }
2858}
2859
2860
2861bool Map::is_access_check_needed() {
2862 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2863}
2864
2865
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002866void Map::set_is_extensible(bool value) {
2867 if (value) {
2868 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2869 } else {
2870 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2871 }
2872}
2873
2874bool Map::is_extensible() {
2875 return ((1 << kIsExtensible) & bit_field2()) != 0;
2876}
2877
2878
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002879void Map::set_attached_to_shared_function_info(bool value) {
2880 if (value) {
2881 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2882 } else {
2883 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2884 }
2885}
2886
2887bool Map::attached_to_shared_function_info() {
2888 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2889}
2890
2891
2892void Map::set_is_shared(bool value) {
2893 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002894 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002895 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002896 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002897 }
2898}
2899
2900bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002901 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002902}
2903
2904
2905JSFunction* Map::unchecked_constructor() {
2906 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2907}
2908
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002909
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002910Code::Flags Code::flags() {
2911 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2912}
2913
2914
2915void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002916 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002917 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002918 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2919 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002920 ExtractArgumentsCountFromFlags(flags) >= 0);
2921 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2922}
2923
2924
2925Code::Kind Code::kind() {
2926 return ExtractKindFromFlags(flags());
2927}
2928
2929
kasper.lund7276f142008-07-30 08:49:36 +00002930InlineCacheState Code::ic_state() {
2931 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002932 // Only allow uninitialized or debugger states for non-IC code
2933 // objects. This is used in the debugger to determine whether or not
2934 // a call to code object has been replaced with a debug break call.
2935 ASSERT(is_inline_cache_stub() ||
2936 result == UNINITIALIZED ||
2937 result == DEBUG_BREAK ||
2938 result == DEBUG_PREPARE_STEP_IN);
2939 return result;
2940}
2941
2942
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002943Code::ExtraICState Code::extra_ic_state() {
2944 ASSERT(is_inline_cache_stub());
2945 return ExtractExtraICStateFromFlags(flags());
2946}
2947
2948
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002949PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002950 return ExtractTypeFromFlags(flags());
2951}
2952
2953
2954int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002955 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002956 return ExtractArgumentsCountFromFlags(flags());
2957}
2958
2959
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002960int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002961 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002962 kind() == UNARY_OP_IC ||
2963 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002964 kind() == COMPARE_IC ||
2965 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002966 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002967}
2968
2969
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002970void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002971 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002972 kind() == UNARY_OP_IC ||
2973 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002974 kind() == COMPARE_IC ||
2975 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002976 ASSERT(0 <= major && major < 256);
2977 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002978}
2979
2980
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002981bool Code::is_pregenerated() {
2982 return kind() == STUB && IsPregeneratedField::decode(flags());
2983}
2984
2985
2986void Code::set_is_pregenerated(bool value) {
2987 ASSERT(kind() == STUB);
2988 Flags f = flags();
2989 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
2990 set_flags(f);
2991}
2992
2993
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002994bool Code::optimizable() {
2995 ASSERT(kind() == FUNCTION);
2996 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2997}
2998
2999
3000void Code::set_optimizable(bool value) {
3001 ASSERT(kind() == FUNCTION);
3002 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3003}
3004
3005
3006bool Code::has_deoptimization_support() {
3007 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00003008 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3009 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003010}
3011
3012
3013void Code::set_has_deoptimization_support(bool value) {
3014 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00003015 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3016 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3017 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3018}
3019
3020
3021bool Code::has_debug_break_slots() {
3022 ASSERT(kind() == FUNCTION);
3023 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3024 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3025}
3026
3027
3028void Code::set_has_debug_break_slots(bool value) {
3029 ASSERT(kind() == FUNCTION);
3030 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3031 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3032 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003033}
3034
3035
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003036bool Code::is_compiled_optimizable() {
3037 ASSERT(kind() == FUNCTION);
3038 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3039 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3040}
3041
3042
3043void Code::set_compiled_optimizable(bool value) {
3044 ASSERT(kind() == FUNCTION);
3045 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3046 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3047 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3048}
3049
3050
yangguo@chromium.orga7d3df92012-02-27 11:46:55 +00003051bool Code::has_self_optimization_header() {
3052 ASSERT(kind() == FUNCTION);
3053 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3054 return FullCodeFlagsHasSelfOptimizationHeader::decode(flags);
3055}
3056
3057
3058void Code::set_self_optimization_header(bool value) {
3059 ASSERT(kind() == FUNCTION);
3060 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3061 flags = FullCodeFlagsHasSelfOptimizationHeader::update(flags, value);
3062 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3063}
3064
3065
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003066int Code::allow_osr_at_loop_nesting_level() {
3067 ASSERT(kind() == FUNCTION);
3068 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3069}
3070
3071
3072void Code::set_allow_osr_at_loop_nesting_level(int level) {
3073 ASSERT(kind() == FUNCTION);
3074 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3075 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3076}
3077
3078
3079unsigned Code::stack_slots() {
3080 ASSERT(kind() == OPTIMIZED_FUNCTION);
3081 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3082}
3083
3084
3085void Code::set_stack_slots(unsigned slots) {
3086 ASSERT(kind() == OPTIMIZED_FUNCTION);
3087 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3088}
3089
3090
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003091unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003092 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003093 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003094}
3095
3096
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003097void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003098 ASSERT(kind() == OPTIMIZED_FUNCTION);
3099 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003100 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003101}
3102
3103
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003104unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003105 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003106 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003107}
3108
3109
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003110void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003111 ASSERT(kind() == FUNCTION);
3112 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003113 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003114}
3115
3116
3117CheckType Code::check_type() {
3118 ASSERT(is_call_stub() || is_keyed_call_stub());
3119 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3120 return static_cast<CheckType>(type);
3121}
3122
3123
3124void Code::set_check_type(CheckType value) {
3125 ASSERT(is_call_stub() || is_keyed_call_stub());
3126 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3127}
3128
3129
danno@chromium.org40cb8782011-05-25 07:58:50 +00003130byte Code::unary_op_type() {
3131 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003132 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3133}
3134
3135
danno@chromium.org40cb8782011-05-25 07:58:50 +00003136void Code::set_unary_op_type(byte value) {
3137 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003138 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3139}
3140
3141
danno@chromium.org40cb8782011-05-25 07:58:50 +00003142byte Code::binary_op_type() {
3143 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003144 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3145}
3146
3147
danno@chromium.org40cb8782011-05-25 07:58:50 +00003148void Code::set_binary_op_type(byte value) {
3149 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003150 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3151}
3152
3153
danno@chromium.org40cb8782011-05-25 07:58:50 +00003154byte Code::binary_op_result_type() {
3155 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003156 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3157}
3158
3159
danno@chromium.org40cb8782011-05-25 07:58:50 +00003160void Code::set_binary_op_result_type(byte value) {
3161 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003162 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3163}
3164
3165
3166byte Code::compare_state() {
3167 ASSERT(is_compare_ic_stub());
3168 return READ_BYTE_FIELD(this, kCompareStateOffset);
3169}
3170
3171
3172void Code::set_compare_state(byte value) {
3173 ASSERT(is_compare_ic_stub());
3174 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3175}
3176
3177
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003178byte Code::to_boolean_state() {
3179 ASSERT(is_to_boolean_ic_stub());
3180 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3181}
3182
3183
3184void Code::set_to_boolean_state(byte value) {
3185 ASSERT(is_to_boolean_ic_stub());
3186 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3187}
3188
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003189
3190bool Code::has_function_cache() {
3191 ASSERT(kind() == STUB);
3192 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3193}
3194
3195
3196void Code::set_has_function_cache(bool flag) {
3197 ASSERT(kind() == STUB);
3198 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3199}
3200
3201
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003202bool Code::is_inline_cache_stub() {
3203 Kind kind = this->kind();
3204 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3205}
3206
3207
3208Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003209 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003210 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003211 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003212 int argc,
3213 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003214 // Extra IC state is only allowed for call IC stubs or for store IC
3215 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003216 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003217 kind == CALL_IC ||
3218 kind == STORE_IC ||
3219 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003220 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003221 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003222 | ICStateField::encode(ic_state)
3223 | TypeField::encode(type)
3224 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003225 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003226 | CacheHolderField::encode(holder);
3227 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003228}
3229
3230
3231Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3232 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003233 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003234 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003235 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003236 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003237}
3238
3239
3240Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003241 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003242}
3243
3244
kasper.lund7276f142008-07-30 08:49:36 +00003245InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003246 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003247}
3248
3249
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003250Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003251 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003252}
3253
3254
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003255PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003256 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003257}
3258
3259
3260int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003261 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003262}
3263
3264
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003265InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003266 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003267}
3268
3269
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003270Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003271 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003272 return static_cast<Flags>(bits);
3273}
3274
3275
ager@chromium.org8bb60582008-12-11 12:02:20 +00003276Code* Code::GetCodeFromTargetAddress(Address address) {
3277 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3278 // GetCodeFromTargetAddress might be called when marking objects during mark
3279 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3280 // Code::cast. Code::cast does not work when the object's map is
3281 // marked.
3282 Code* result = reinterpret_cast<Code*>(code);
3283 return result;
3284}
3285
3286
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003287Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3288 return HeapObject::
3289 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3290}
3291
3292
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003293Object* Map::prototype() {
3294 return READ_FIELD(this, kPrototypeOffset);
3295}
3296
3297
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003298void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003299 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003300 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003301 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003302}
3303
3304
danno@chromium.org40cb8782011-05-25 07:58:50 +00003305DescriptorArray* Map::instance_descriptors() {
3306 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3307 if (object->IsSmi()) {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003308 return GetHeap()->empty_descriptor_array();
danno@chromium.org40cb8782011-05-25 07:58:50 +00003309 } else {
3310 return DescriptorArray::cast(object);
3311 }
3312}
3313
3314
3315void Map::init_instance_descriptors() {
3316 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3317}
3318
3319
3320void Map::clear_instance_descriptors() {
3321 Object* object = READ_FIELD(this,
3322 kInstanceDescriptorsOrBitField3Offset);
3323 if (!object->IsSmi()) {
3324 WRITE_FIELD(
3325 this,
3326 kInstanceDescriptorsOrBitField3Offset,
3327 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3328 }
3329}
3330
3331
3332void Map::set_instance_descriptors(DescriptorArray* value,
3333 WriteBarrierMode mode) {
3334 Object* object = READ_FIELD(this,
3335 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003336 Heap* heap = GetHeap();
3337 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003338 clear_instance_descriptors();
3339 return;
3340 } else {
3341 if (object->IsSmi()) {
3342 value->set_bit_field3_storage(Smi::cast(object)->value());
3343 } else {
3344 value->set_bit_field3_storage(
3345 DescriptorArray::cast(object)->bit_field3_storage());
3346 }
3347 }
3348 ASSERT(!is_shared());
3349 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003350 CONDITIONAL_WRITE_BARRIER(
3351 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003352}
3353
3354
3355int Map::bit_field3() {
3356 Object* object = READ_FIELD(this,
3357 kInstanceDescriptorsOrBitField3Offset);
3358 if (object->IsSmi()) {
3359 return Smi::cast(object)->value();
3360 } else {
3361 return DescriptorArray::cast(object)->bit_field3_storage();
3362 }
3363}
3364
3365
3366void Map::set_bit_field3(int value) {
3367 ASSERT(Smi::IsValid(value));
3368 Object* object = READ_FIELD(this,
3369 kInstanceDescriptorsOrBitField3Offset);
3370 if (object->IsSmi()) {
3371 WRITE_FIELD(this,
3372 kInstanceDescriptorsOrBitField3Offset,
3373 Smi::FromInt(value));
3374 } else {
3375 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3376 }
3377}
3378
3379
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003380FixedArray* Map::unchecked_prototype_transitions() {
3381 return reinterpret_cast<FixedArray*>(
3382 READ_FIELD(this, kPrototypeTransitionsOffset));
3383}
3384
3385
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003386ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003387ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003388ACCESSORS(Map, constructor, Object, kConstructorOffset)
3389
3390ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003391ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003392ACCESSORS(JSFunction,
3393 next_function_link,
3394 Object,
3395 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003396
3397ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3398ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003399ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003400
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003401ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003402
3403ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3404ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3405ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3406ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003407ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003408
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003409ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3410ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3411
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003412ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3413ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3414ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3415
3416ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3417ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3418ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3419ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3420ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3421ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3422
3423ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3424ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3425
3426ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3427ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3428
3429ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3430ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003431ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3432 kPropertyAccessorsOffset)
3433ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3434 kPrototypeTemplateOffset)
3435ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3436ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3437 kNamedPropertyHandlerOffset)
3438ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3439 kIndexedPropertyHandlerOffset)
3440ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3441 kInstanceTemplateOffset)
3442ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3443ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003444ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3445 kInstanceCallHandlerOffset)
3446ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3447 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003448ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003449
3450ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003451ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3452 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003453
3454ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3455ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3456
3457ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3458
3459ACCESSORS(Script, source, Object, kSourceOffset)
3460ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003461ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003462ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
3463ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003464ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003465ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003466ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003467ACCESSORS_TO_SMI(Script, type, kTypeOffset)
3468ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
3469ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003470ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003471ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003472ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
3473 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003474
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003475#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003476ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3477ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3478ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3479ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3480
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003481ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
3482ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
3483ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003484ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003485#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003486
3487ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003488ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3489ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003490ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3491 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003492ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003493ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3494ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003495ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003496ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3497 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003498
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00003499SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset)
3500
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003501BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3502 kHiddenPrototypeBit)
3503BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3504BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3505 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003506BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3507 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003508BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3509 kIsExpressionBit)
3510BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3511 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003512BOOL_GETTER(SharedFunctionInfo,
3513 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003514 has_only_simple_this_property_assignments,
3515 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003516BOOL_ACCESSORS(SharedFunctionInfo,
3517 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003518 allows_lazy_compilation,
3519 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003520BOOL_ACCESSORS(SharedFunctionInfo,
3521 compiler_hints,
3522 uses_arguments,
3523 kUsesArguments)
3524BOOL_ACCESSORS(SharedFunctionInfo,
3525 compiler_hints,
3526 has_duplicate_parameters,
3527 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003528
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003529
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003530#if V8_HOST_ARCH_32_BIT
3531SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3532SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003533 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003534SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003535 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003536SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3537SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003538 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003539SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3540SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003541 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003542SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003543 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003544SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003545 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003546SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003547SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3548SMI_ACCESSORS(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003549#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003550
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003551#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003552 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003553 int holder::name() { \
3554 int value = READ_INT_FIELD(this, offset); \
3555 ASSERT(kHeapObjectTag == 1); \
3556 ASSERT((value & kHeapObjectTag) == 0); \
3557 return value >> 1; \
3558 } \
3559 void holder::set_##name(int value) { \
3560 ASSERT(kHeapObjectTag == 1); \
3561 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3562 (value & 0xC0000000) == 0x000000000); \
3563 WRITE_INT_FIELD(this, \
3564 offset, \
3565 (value << 1) & ~kHeapObjectTag); \
3566 }
3567
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003568#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3569 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003570 INT_ACCESSORS(holder, name, offset)
3571
3572
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003573PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003574PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3575 formal_parameter_count,
3576 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003577
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003578PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3579 expected_nof_properties,
3580 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003581PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3582
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003583PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3584PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3585 start_position_and_type,
3586 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003587
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003588PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3589 function_token_position,
3590 kFunctionTokenPositionOffset)
3591PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3592 compiler_hints,
3593 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003594
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003595PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3596 this_property_assignments_count,
3597 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003598PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003599
3600PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3601PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003602#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003603
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003604
3605int SharedFunctionInfo::construction_count() {
3606 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3607}
3608
3609
3610void SharedFunctionInfo::set_construction_count(int value) {
3611 ASSERT(0 <= value && value < 256);
3612 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3613}
3614
3615
whesse@chromium.org7b260152011-06-20 15:33:18 +00003616BOOL_ACCESSORS(SharedFunctionInfo,
3617 compiler_hints,
3618 live_objects_may_exist,
3619 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003620
3621
3622bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003623 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003624}
3625
3626
whesse@chromium.org7b260152011-06-20 15:33:18 +00003627BOOL_GETTER(SharedFunctionInfo,
3628 compiler_hints,
3629 optimization_disabled,
3630 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003631
3632
3633void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3634 set_compiler_hints(BooleanBit::set(compiler_hints(),
3635 kOptimizationDisabled,
3636 disable));
3637 // If disabling optimizations we reflect that in the code object so
3638 // it will not be counted as optimizable code.
3639 if ((code()->kind() == Code::FUNCTION) && disable) {
3640 code()->set_optimizable(false);
3641 }
3642}
3643
3644
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003645LanguageMode SharedFunctionInfo::language_mode() {
3646 int hints = compiler_hints();
3647 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3648 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3649 return EXTENDED_MODE;
3650 }
3651 return BooleanBit::get(hints, kStrictModeFunction)
3652 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003653}
3654
3655
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003656void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3657 // We only allow language mode transitions that go set the same language mode
3658 // again or go up in the chain:
3659 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3660 ASSERT(this->language_mode() == CLASSIC_MODE ||
3661 this->language_mode() == language_mode ||
3662 language_mode == EXTENDED_MODE);
3663 int hints = compiler_hints();
3664 hints = BooleanBit::set(
3665 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3666 hints = BooleanBit::set(
3667 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3668 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003669}
3670
3671
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003672bool SharedFunctionInfo::is_classic_mode() {
3673 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3674}
3675
3676BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3677 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003678BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3679BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3680 name_should_print_as_anonymous,
3681 kNameShouldPrintAsAnonymous)
3682BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3683BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00003684BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
3685BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
3686 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003687BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003688
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003689ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3690ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3691
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003692ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3693
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003694bool Script::HasValidSource() {
3695 Object* src = this->source();
3696 if (!src->IsString()) return true;
3697 String* src_str = String::cast(src);
3698 if (!StringShape(src_str).IsExternal()) return true;
3699 if (src_str->IsAsciiRepresentation()) {
3700 return ExternalAsciiString::cast(src)->resource() != NULL;
3701 } else if (src_str->IsTwoByteRepresentation()) {
3702 return ExternalTwoByteString::cast(src)->resource() != NULL;
3703 }
3704 return true;
3705}
3706
3707
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003708void SharedFunctionInfo::DontAdaptArguments() {
3709 ASSERT(code()->kind() == Code::BUILTIN);
3710 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3711}
3712
3713
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003714int SharedFunctionInfo::start_position() {
3715 return start_position_and_type() >> kStartPositionShift;
3716}
3717
3718
3719void SharedFunctionInfo::set_start_position(int start_position) {
3720 set_start_position_and_type((start_position << kStartPositionShift)
3721 | (start_position_and_type() & ~kStartPositionMask));
3722}
3723
3724
3725Code* SharedFunctionInfo::code() {
3726 return Code::cast(READ_FIELD(this, kCodeOffset));
3727}
3728
3729
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003730Code* SharedFunctionInfo::unchecked_code() {
3731 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3732}
3733
3734
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003735void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003736 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003737 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003738}
3739
3740
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003741ScopeInfo* SharedFunctionInfo::scope_info() {
3742 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003743}
3744
3745
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003746void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003747 WriteBarrierMode mode) {
3748 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003749 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3750 this,
3751 kScopeInfoOffset,
3752 reinterpret_cast<Object*>(value),
3753 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003754}
3755
3756
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003757bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003758 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003759 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003760}
3761
3762
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003763bool SharedFunctionInfo::IsApiFunction() {
3764 return function_data()->IsFunctionTemplateInfo();
3765}
3766
3767
3768FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3769 ASSERT(IsApiFunction());
3770 return FunctionTemplateInfo::cast(function_data());
3771}
3772
3773
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003774bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003775 return function_data()->IsSmi();
3776}
3777
3778
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003779BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3780 ASSERT(HasBuiltinFunctionId());
3781 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003782}
3783
3784
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003785int SharedFunctionInfo::code_age() {
3786 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3787}
3788
3789
3790void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00003791 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3792 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003793}
3794
3795
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003796bool SharedFunctionInfo::has_deoptimization_support() {
3797 Code* code = this->code();
3798 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3799}
3800
3801
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003802bool JSFunction::IsBuiltin() {
3803 return context()->global()->IsJSBuiltinsObject();
3804}
3805
3806
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003807bool JSFunction::NeedsArgumentsAdaption() {
3808 return shared()->formal_parameter_count() !=
3809 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3810}
3811
3812
3813bool JSFunction::IsOptimized() {
3814 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3815}
3816
3817
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003818bool JSFunction::IsOptimizable() {
3819 return code()->kind() == Code::FUNCTION && code()->optimizable();
3820}
3821
3822
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003823bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003824 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003825}
3826
3827
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003828Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003829 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003830}
3831
3832
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003833Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003834 return reinterpret_cast<Code*>(
3835 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003836}
3837
3838
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003839void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003840 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003841 Address entry = value->entry();
3842 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003843 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3844 this,
3845 HeapObject::RawField(this, kCodeEntryOffset),
3846 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003847}
3848
3849
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003850void JSFunction::ReplaceCode(Code* code) {
3851 bool was_optimized = IsOptimized();
3852 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3853
3854 set_code(code);
3855
3856 // Add/remove the function from the list of optimized functions for this
3857 // context based on the state change.
3858 if (!was_optimized && is_optimized) {
3859 context()->global_context()->AddOptimizedFunction(this);
3860 }
3861 if (was_optimized && !is_optimized) {
3862 context()->global_context()->RemoveOptimizedFunction(this);
3863 }
3864}
3865
3866
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003867Context* JSFunction::context() {
3868 return Context::cast(READ_FIELD(this, kContextOffset));
3869}
3870
3871
3872Object* JSFunction::unchecked_context() {
3873 return READ_FIELD(this, kContextOffset);
3874}
3875
3876
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003877SharedFunctionInfo* JSFunction::unchecked_shared() {
3878 return reinterpret_cast<SharedFunctionInfo*>(
3879 READ_FIELD(this, kSharedFunctionInfoOffset));
3880}
3881
3882
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003883void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003884 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003885 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003886 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003887}
3888
3889ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3890 kPrototypeOrInitialMapOffset)
3891
3892
3893Map* JSFunction::initial_map() {
3894 return Map::cast(prototype_or_initial_map());
3895}
3896
3897
3898void JSFunction::set_initial_map(Map* value) {
3899 set_prototype_or_initial_map(value);
3900}
3901
3902
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003903MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
3904 Map* initial_map) {
3905 Context* global_context = context()->global_context();
3906 Object* array_function =
3907 global_context->get(Context::ARRAY_FUNCTION_INDEX);
3908 if (array_function->IsJSFunction() &&
3909 this == JSFunction::cast(array_function)) {
3910 ASSERT(initial_map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
3911
3912 MaybeObject* maybe_map = initial_map->CopyDropTransitions();
3913 Map* new_double_map = NULL;
3914 if (!maybe_map->To<Map>(&new_double_map)) return maybe_map;
3915 new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00003916 maybe_map = initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS,
3917 new_double_map);
3918 if (maybe_map->IsFailure()) return maybe_map;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003919
3920 maybe_map = new_double_map->CopyDropTransitions();
3921 Map* new_object_map = NULL;
3922 if (!maybe_map->To<Map>(&new_object_map)) return maybe_map;
3923 new_object_map->set_elements_kind(FAST_ELEMENTS);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00003924 maybe_map = new_double_map->AddElementsTransition(FAST_ELEMENTS,
3925 new_object_map);
3926 if (maybe_map->IsFailure()) return maybe_map;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003927
3928 global_context->set_smi_js_array_map(initial_map);
3929 global_context->set_double_js_array_map(new_double_map);
3930 global_context->set_object_js_array_map(new_object_map);
3931 }
3932 set_initial_map(initial_map);
3933 return this;
3934}
3935
3936
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003937bool JSFunction::has_initial_map() {
3938 return prototype_or_initial_map()->IsMap();
3939}
3940
3941
3942bool JSFunction::has_instance_prototype() {
3943 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3944}
3945
3946
3947bool JSFunction::has_prototype() {
3948 return map()->has_non_instance_prototype() || has_instance_prototype();
3949}
3950
3951
3952Object* JSFunction::instance_prototype() {
3953 ASSERT(has_instance_prototype());
3954 if (has_initial_map()) return initial_map()->prototype();
3955 // When there is no initial map and the prototype is a JSObject, the
3956 // initial map field is used for the prototype field.
3957 return prototype_or_initial_map();
3958}
3959
3960
3961Object* JSFunction::prototype() {
3962 ASSERT(has_prototype());
3963 // If the function's prototype property has been set to a non-JSObject
3964 // value, that value is stored in the constructor field of the map.
3965 if (map()->has_non_instance_prototype()) return map()->constructor();
3966 return instance_prototype();
3967}
3968
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003969bool JSFunction::should_have_prototype() {
3970 return map()->function_with_prototype();
3971}
3972
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003973
3974bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003975 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003976}
3977
3978
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003979FixedArray* JSFunction::literals() {
3980 ASSERT(!shared()->bound());
3981 return literals_or_bindings();
3982}
3983
3984
3985void JSFunction::set_literals(FixedArray* literals) {
3986 ASSERT(!shared()->bound());
3987 set_literals_or_bindings(literals);
3988}
3989
3990
3991FixedArray* JSFunction::function_bindings() {
3992 ASSERT(shared()->bound());
3993 return literals_or_bindings();
3994}
3995
3996
3997void JSFunction::set_function_bindings(FixedArray* bindings) {
3998 ASSERT(shared()->bound());
3999 // Bound function literal may be initialized to the empty fixed array
4000 // before the bindings are set.
4001 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4002 bindings->map() == GetHeap()->fixed_cow_array_map());
4003 set_literals_or_bindings(bindings);
4004}
4005
4006
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004007int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004008 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004009 return literals()->length();
4010}
4011
4012
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004013Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004014 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004015 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004016}
4017
4018
4019void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4020 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004021 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004022 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004023 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004024}
4025
4026
4027Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004028 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004029 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4030}
4031
4032
4033void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4034 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004035 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004036 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004037 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004038}
4039
4040
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004041ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004042ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004043ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4044ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4045
4046
4047void JSProxy::InitializeBody(int object_size, Object* value) {
4048 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4049 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4050 WRITE_FIELD(this, offset, value);
4051 }
4052}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004053
4054
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004055ACCESSORS(JSSet, table, Object, kTableOffset)
4056ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004057ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4058ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004059
4060
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004061Address Foreign::foreign_address() {
4062 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004063}
4064
4065
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004066void Foreign::set_foreign_address(Address value) {
4067 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004068}
4069
4070
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004071ACCESSORS(JSValue, value, Object, kValueOffset)
4072
4073
4074JSValue* JSValue::cast(Object* obj) {
4075 ASSERT(obj->IsJSValue());
4076 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4077 return reinterpret_cast<JSValue*>(obj);
4078}
4079
4080
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004081ACCESSORS(JSDate, value, Object, kValueOffset)
4082ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4083ACCESSORS(JSDate, year, Object, kYearOffset)
4084ACCESSORS(JSDate, month, Object, kMonthOffset)
4085ACCESSORS(JSDate, day, Object, kDayOffset)
4086ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4087ACCESSORS(JSDate, hour, Object, kHourOffset)
4088ACCESSORS(JSDate, min, Object, kMinOffset)
4089ACCESSORS(JSDate, sec, Object, kSecOffset)
4090
4091
4092JSDate* JSDate::cast(Object* obj) {
4093 ASSERT(obj->IsJSDate());
4094 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4095 return reinterpret_cast<JSDate*>(obj);
4096}
4097
4098
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004099ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4100ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4101ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4102ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4103ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4104SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4105SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4106
4107
4108JSMessageObject* JSMessageObject::cast(Object* obj) {
4109 ASSERT(obj->IsJSMessageObject());
4110 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4111 return reinterpret_cast<JSMessageObject*>(obj);
4112}
4113
4114
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004115INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004116ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004117ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004118ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004119ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004120ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004121
4122
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004123byte* Code::instruction_start() {
4124 return FIELD_ADDR(this, kHeaderSize);
4125}
4126
4127
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004128byte* Code::instruction_end() {
4129 return instruction_start() + instruction_size();
4130}
4131
4132
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004133int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004134 return RoundUp(instruction_size(), kObjectAlignment);
4135}
4136
4137
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004138FixedArray* Code::unchecked_deoptimization_data() {
4139 return reinterpret_cast<FixedArray*>(
4140 READ_FIELD(this, kDeoptimizationDataOffset));
4141}
4142
4143
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004144ByteArray* Code::unchecked_relocation_info() {
4145 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004146}
4147
4148
4149byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004150 return unchecked_relocation_info()->GetDataStartAddress();
4151}
4152
4153
4154int Code::relocation_size() {
4155 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004156}
4157
4158
4159byte* Code::entry() {
4160 return instruction_start();
4161}
4162
4163
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004164bool Code::contains(byte* inner_pointer) {
4165 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004166}
4167
4168
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004169ACCESSORS(JSArray, length, Object, kLengthOffset)
4170
4171
ager@chromium.org236ad962008-09-25 09:45:57 +00004172ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004173
4174
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004175JSRegExp::Type JSRegExp::TypeTag() {
4176 Object* data = this->data();
4177 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4178 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4179 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004180}
4181
4182
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004183JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4184 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4185 return static_cast<JSRegExp::Type>(smi->value());
4186}
4187
4188
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004189int JSRegExp::CaptureCount() {
4190 switch (TypeTag()) {
4191 case ATOM:
4192 return 0;
4193 case IRREGEXP:
4194 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4195 default:
4196 UNREACHABLE();
4197 return -1;
4198 }
4199}
4200
4201
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004202JSRegExp::Flags JSRegExp::GetFlags() {
4203 ASSERT(this->data()->IsFixedArray());
4204 Object* data = this->data();
4205 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4206 return Flags(smi->value());
4207}
4208
4209
4210String* JSRegExp::Pattern() {
4211 ASSERT(this->data()->IsFixedArray());
4212 Object* data = this->data();
4213 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4214 return pattern;
4215}
4216
4217
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004218Object* JSRegExp::DataAt(int index) {
4219 ASSERT(TypeTag() != NOT_COMPILED);
4220 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004221}
4222
4223
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004224Object* JSRegExp::DataAtUnchecked(int index) {
4225 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4226 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4227 return READ_FIELD(fa, offset);
4228}
4229
4230
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004231void JSRegExp::SetDataAt(int index, Object* value) {
4232 ASSERT(TypeTag() != NOT_COMPILED);
4233 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4234 FixedArray::cast(data())->set(index, value);
4235}
4236
4237
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004238void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4239 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4240 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4241 if (value->IsSmi()) {
4242 fa->set_unchecked(index, Smi::cast(value));
4243 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004244 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004245 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4246 }
4247}
4248
4249
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004250ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004251 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004252#if DEBUG
4253 FixedArrayBase* fixed_array =
4254 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4255 Map* map = fixed_array->map();
4256 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004257 (map == GetHeap()->fixed_array_map() ||
4258 map == GetHeap()->fixed_cow_array_map())) ||
4259 (kind == FAST_DOUBLE_ELEMENTS &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004260 (fixed_array->IsFixedDoubleArray() ||
4261 fixed_array == GetHeap()->empty_fixed_array())) ||
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004262 (kind == DICTIONARY_ELEMENTS &&
4263 fixed_array->IsFixedArray() &&
4264 fixed_array->IsDictionary()) ||
4265 (kind > DICTIONARY_ELEMENTS));
4266 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4267 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004268#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004269 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004270}
4271
4272
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004273ElementsAccessor* JSObject::GetElementsAccessor() {
4274 return ElementsAccessor::ForKind(GetElementsKind());
4275}
4276
4277
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004278bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004279 return GetElementsKind() == FAST_ELEMENTS;
4280}
4281
4282
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004283bool JSObject::HasFastSmiOnlyElements() {
4284 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4285}
4286
4287
4288bool JSObject::HasFastTypeElements() {
4289 ElementsKind elements_kind = GetElementsKind();
4290 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4291 elements_kind == FAST_ELEMENTS;
4292}
4293
4294
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004295bool JSObject::HasFastDoubleElements() {
4296 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4297}
4298
4299
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004300bool JSObject::HasDictionaryElements() {
4301 return GetElementsKind() == DICTIONARY_ELEMENTS;
4302}
4303
4304
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004305bool JSObject::HasNonStrictArgumentsElements() {
4306 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4307}
4308
4309
ager@chromium.org3811b432009-10-28 14:53:37 +00004310bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004311 HeapObject* array = elements();
4312 ASSERT(array != NULL);
4313 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004314}
4315
4316
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004317#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4318bool JSObject::HasExternal##name##Elements() { \
4319 HeapObject* array = elements(); \
4320 ASSERT(array != NULL); \
4321 if (!array->IsHeapObject()) \
4322 return false; \
4323 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004324}
4325
4326
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004327EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4328EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4329EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4330EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4331 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4332EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4333EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4334 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4335EXTERNAL_ELEMENTS_CHECK(Float,
4336 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004337EXTERNAL_ELEMENTS_CHECK(Double,
4338 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004339EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004340
4341
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004342bool JSObject::HasNamedInterceptor() {
4343 return map()->has_named_interceptor();
4344}
4345
4346
4347bool JSObject::HasIndexedInterceptor() {
4348 return map()->has_indexed_interceptor();
4349}
4350
4351
lrn@chromium.org303ada72010-10-27 09:33:13 +00004352MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004353 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004354 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004355 Isolate* isolate = GetIsolate();
4356 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004357 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004358 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4359 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004360 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4361 return maybe_writable_elems;
4362 }
4363 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004364 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004365 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004366 return writable_elems;
4367}
4368
4369
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004370StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004371 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004372 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004373}
4374
4375
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004376SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004377 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004378 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004379}
4380
4381
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004382bool String::IsHashFieldComputed(uint32_t field) {
4383 return (field & kHashNotComputedMask) == 0;
4384}
4385
4386
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004387bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004388 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004389}
4390
4391
4392uint32_t String::Hash() {
4393 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004394 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004395 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004396 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004397 return ComputeAndSetHash();
4398}
4399
4400
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004401StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004402 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004403 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004404 array_index_(0),
4405 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4406 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004407 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004408 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004409}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004410
4411
4412bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004413 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004414}
4415
4416
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004417void StringHasher::AddCharacter(uint32_t c) {
4418 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4419 AddSurrogatePair(c); // Not inlined.
4420 return;
4421 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004422 // Use the Jenkins one-at-a-time hash function to update the hash
4423 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004424 raw_running_hash_ += c;
4425 raw_running_hash_ += (raw_running_hash_ << 10);
4426 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004427 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004428 if (is_array_index_) {
4429 if (c < '0' || c > '9') {
4430 is_array_index_ = false;
4431 } else {
4432 int d = c - '0';
4433 if (is_first_char_) {
4434 is_first_char_ = false;
4435 if (c == '0' && length_ > 1) {
4436 is_array_index_ = false;
4437 return;
4438 }
4439 }
4440 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4441 is_array_index_ = false;
4442 } else {
4443 array_index_ = array_index_ * 10 + d;
4444 }
4445 }
4446 }
4447}
4448
4449
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004450void StringHasher::AddCharacterNoIndex(uint32_t c) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00004451 ASSERT(!is_array_index());
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004452 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4453 AddSurrogatePairNoIndex(c); // Not inlined.
4454 return;
4455 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004456 raw_running_hash_ += c;
4457 raw_running_hash_ += (raw_running_hash_ << 10);
4458 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4459}
4460
4461
4462uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004463 // Get the calculated raw hash value and do some more bit ops to distribute
4464 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004465 uint32_t result = raw_running_hash_;
4466 result += (result << 3);
4467 result ^= (result >> 11);
4468 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004469 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004470 result = 27;
4471 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004472 return result;
4473}
4474
4475
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004476template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004477uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4478 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004479 if (!hasher.has_trivial_hash()) {
4480 int i;
4481 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4482 hasher.AddCharacter(chars[i]);
4483 }
4484 for (; i < length; i++) {
4485 hasher.AddCharacterNoIndex(chars[i]);
4486 }
4487 }
4488 return hasher.GetHashField();
4489}
4490
4491
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004492bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004493 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004494 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4495 return false;
4496 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004497 return SlowAsArrayIndex(index);
4498}
4499
4500
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004501Object* JSReceiver::GetPrototype() {
4502 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004503}
4504
4505
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004506bool JSReceiver::HasProperty(String* name) {
4507 if (IsJSProxy()) {
4508 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4509 }
4510 return GetPropertyAttribute(name) != ABSENT;
4511}
4512
4513
4514bool JSReceiver::HasLocalProperty(String* name) {
4515 if (IsJSProxy()) {
4516 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4517 }
4518 return GetLocalPropertyAttribute(name) != ABSENT;
4519}
4520
4521
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004522PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004523 return GetPropertyAttributeWithReceiver(this, key);
4524}
4525
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004526// TODO(504): this may be useful in other places too where JSGlobalProxy
4527// is used.
4528Object* JSObject::BypassGlobalProxy() {
4529 if (IsJSGlobalProxy()) {
4530 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004531 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004532 ASSERT(proto->IsJSGlobalObject());
4533 return proto;
4534 }
4535 return this;
4536}
4537
4538
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004539MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4540 return IsJSProxy()
4541 ? JSProxy::cast(this)->GetIdentityHash(flag)
4542 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004543}
4544
4545
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004546bool JSReceiver::HasElement(uint32_t index) {
4547 if (IsJSProxy()) {
4548 return JSProxy::cast(this)->HasElementWithHandler(index);
4549 }
4550 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004551}
4552
4553
4554bool AccessorInfo::all_can_read() {
4555 return BooleanBit::get(flag(), kAllCanReadBit);
4556}
4557
4558
4559void AccessorInfo::set_all_can_read(bool value) {
4560 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4561}
4562
4563
4564bool AccessorInfo::all_can_write() {
4565 return BooleanBit::get(flag(), kAllCanWriteBit);
4566}
4567
4568
4569void AccessorInfo::set_all_can_write(bool value) {
4570 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4571}
4572
4573
ager@chromium.org870a0b62008-11-04 11:43:05 +00004574bool AccessorInfo::prohibits_overwriting() {
4575 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4576}
4577
4578
4579void AccessorInfo::set_prohibits_overwriting(bool value) {
4580 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4581}
4582
4583
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004584PropertyAttributes AccessorInfo::property_attributes() {
4585 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4586}
4587
4588
4589void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004590 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004591}
4592
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004593
4594template<typename Shape, typename Key>
4595void Dictionary<Shape, Key>::SetEntry(int entry,
4596 Object* key,
4597 Object* value) {
4598 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4599}
4600
4601
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004602template<typename Shape, typename Key>
4603void Dictionary<Shape, Key>::SetEntry(int entry,
4604 Object* key,
4605 Object* value,
4606 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004607 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004608 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004609 AssertNoAllocation no_gc;
4610 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004611 FixedArray::set(index, key, mode);
4612 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004613 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004614}
4615
4616
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004617bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4618 ASSERT(other->IsNumber());
4619 return key == static_cast<uint32_t>(other->Number());
4620}
4621
4622
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004623uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
4624 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004625}
4626
4627
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004628uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
4629 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004630 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004631 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004632}
4633
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004634uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
4635 return ComputeIntegerHash(key, seed);
4636}
4637
4638uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
4639 uint32_t seed,
4640 Object* other) {
4641 ASSERT(other->IsNumber());
4642 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
4643}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004644
4645MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4646 return Isolate::Current()->heap()->NumberFromUint32(key);
4647}
4648
4649
4650bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4651 // We know that all entries in a hash table had their hash keys created.
4652 // Use that knowledge to have fast failure.
4653 if (key->Hash() != String::cast(other)->Hash()) return false;
4654 return key->Equals(String::cast(other));
4655}
4656
4657
4658uint32_t StringDictionaryShape::Hash(String* key) {
4659 return key->Hash();
4660}
4661
4662
4663uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4664 return String::cast(other)->Hash();
4665}
4666
4667
4668MaybeObject* StringDictionaryShape::AsObject(String* key) {
4669 return key;
4670}
4671
4672
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004673template <int entrysize>
4674bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4675 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004676}
4677
4678
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004679template <int entrysize>
4680uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004681 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4682 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004683}
4684
4685
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004686template <int entrysize>
4687uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4688 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004689 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4690 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004691}
4692
4693
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004694template <int entrysize>
4695MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004696 return key;
4697}
4698
4699
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004700void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004701 // No write barrier is needed since empty_fixed_array is not in new space.
4702 // Please note this function is used during marking:
4703 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004704 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4705 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004706}
4707
4708
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004709void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004710 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004711 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004712 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4713 if (elts->length() < required_size) {
4714 // Doubling in size would be overkill, but leave some slack to avoid
4715 // constantly growing.
4716 Expand(required_size + (required_size >> 3));
4717 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004718 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004719 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4720 // Expand will allocate a new backing store in new space even if the size
4721 // we asked for isn't larger than what we had before.
4722 Expand(required_size);
4723 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004724}
4725
4726
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004727void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004728 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004729 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4730}
4731
4732
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004733bool JSArray::AllowsSetElementsLength() {
4734 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4735 ASSERT(result == !HasExternalArrayElements());
4736 return result;
4737}
4738
4739
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004740MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4741 MaybeObject* maybe_result = EnsureCanContainElements(
4742 storage, ALLOW_COPIED_DOUBLE_ELEMENTS);
4743 if (maybe_result->IsFailure()) return maybe_result;
4744 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4745 GetElementsKind() == FAST_DOUBLE_ELEMENTS) ||
4746 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4747 ((GetElementsKind() == FAST_ELEMENTS) ||
4748 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS &&
4749 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004750 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004751 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004752 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004753}
4754
4755
lrn@chromium.org303ada72010-10-27 09:33:13 +00004756MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004757 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004758 return GetHeap()->CopyFixedArray(this);
4759}
4760
4761
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004762MaybeObject* FixedDoubleArray::Copy() {
4763 if (length() == 0) return this;
4764 return GetHeap()->CopyFixedDoubleArray(this);
4765}
4766
4767
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004768void TypeFeedbackCells::SetAstId(int index, Smi* id) {
4769 set(1 + index * 2, id);
4770}
4771
4772
4773Smi* TypeFeedbackCells::AstId(int index) {
4774 return Smi::cast(get(1 + index * 2));
4775}
4776
4777
4778void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
4779 set(index * 2, cell);
4780}
4781
4782
4783JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
4784 return JSGlobalPropertyCell::cast(get(index * 2));
4785}
4786
4787
4788Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
4789 return isolate->factory()->the_hole_value();
4790}
4791
4792
4793Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
4794 return isolate->factory()->undefined_value();
4795}
4796
4797
4798Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
4799 return heap->raw_unchecked_the_hole_value();
4800}
4801
4802
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004803SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
4804SMI_ACCESSORS(TypeFeedbackInfo, ic_with_typeinfo_count,
4805 kIcWithTypeinfoCountOffset)
4806ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
4807 kTypeFeedbackCellsOffset)
4808
4809
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00004810SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
4811
4812
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004813Relocatable::Relocatable(Isolate* isolate) {
4814 ASSERT(isolate == Isolate::Current());
4815 isolate_ = isolate;
4816 prev_ = isolate->relocatable_top();
4817 isolate->set_relocatable_top(this);
4818}
4819
4820
4821Relocatable::~Relocatable() {
4822 ASSERT(isolate_ == Isolate::Current());
4823 ASSERT_EQ(isolate_->relocatable_top(), this);
4824 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004825}
4826
4827
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004828int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4829 return map->instance_size();
4830}
4831
4832
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004833void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004834 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004835 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004836}
4837
4838
4839template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004840void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004841 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004842 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004843}
4844
4845
4846void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4847 typedef v8::String::ExternalAsciiStringResource Resource;
4848 v->VisitExternalAsciiString(
4849 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4850}
4851
4852
4853template<typename StaticVisitor>
4854void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4855 typedef v8::String::ExternalAsciiStringResource Resource;
4856 StaticVisitor::VisitExternalAsciiString(
4857 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4858}
4859
4860
4861void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4862 typedef v8::String::ExternalStringResource Resource;
4863 v->VisitExternalTwoByteString(
4864 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4865}
4866
4867
4868template<typename StaticVisitor>
4869void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4870 typedef v8::String::ExternalStringResource Resource;
4871 StaticVisitor::VisitExternalTwoByteString(
4872 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4873}
4874
4875#define SLOT_ADDR(obj, offset) \
4876 reinterpret_cast<Object**>((obj)->address() + offset)
4877
4878template<int start_offset, int end_offset, int size>
4879void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4880 HeapObject* obj,
4881 ObjectVisitor* v) {
4882 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4883}
4884
4885
4886template<int start_offset>
4887void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4888 int object_size,
4889 ObjectVisitor* v) {
4890 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4891}
4892
4893#undef SLOT_ADDR
4894
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004895#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004896#undef CAST_ACCESSOR
4897#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004898#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004899#undef ACCESSORS_TO_SMI
4900#undef SMI_ACCESSORS
4901#undef BOOL_GETTER
4902#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004903#undef FIELD_ADDR
4904#undef READ_FIELD
4905#undef WRITE_FIELD
4906#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004907#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004908#undef READ_DOUBLE_FIELD
4909#undef WRITE_DOUBLE_FIELD
4910#undef READ_INT_FIELD
4911#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004912#undef READ_INTPTR_FIELD
4913#undef WRITE_INTPTR_FIELD
4914#undef READ_UINT32_FIELD
4915#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004916#undef READ_SHORT_FIELD
4917#undef WRITE_SHORT_FIELD
4918#undef READ_BYTE_FIELD
4919#undef WRITE_BYTE_FIELD
4920
4921
4922} } // namespace v8::internal
4923
4924#endif // V8_OBJECTS_INL_H_