blob: eb1586ad0c2802b63cff7a299f3ae87c0297268d [file] [log] [blame]
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001// Copyright 2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27//
28// Review notes:
29//
ager@chromium.org32912102009-01-16 10:38:43 +000030// - The use of macros in these inline functions may seem superfluous
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000031// but it is absolutely needed to make sure gcc generates optimal
32// code. gcc is not happy when attempting to inline too deep.
33//
34
35#ifndef V8_OBJECTS_INL_H_
36#define V8_OBJECTS_INL_H_
37
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +000038#include "elements.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000039#include "objects.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000040#include "contexts.h"
41#include "conversions-inl.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000042#include "heap.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000043#include "isolate.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000044#include "property.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000045#include "spaces.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000046#include "store-buffer.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000047#include "v8memory.h"
danno@chromium.orgfa458e42012-02-01 10:48:36 +000048#include "factory.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000049#include "incremental-marking.h"
50
kasperl@chromium.org71affb52009-05-26 05:44:31 +000051namespace v8 {
52namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000053
54PropertyDetails::PropertyDetails(Smi* smi) {
55 value_ = smi->value();
56}
57
58
59Smi* PropertyDetails::AsSmi() {
60 return Smi::FromInt(value_);
61}
62
63
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000064PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000065 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000066 return PropertyDetails(smi);
67}
68
69
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000070#define TYPE_CHECKER(type, instancetype) \
71 bool Object::Is##type() { \
72 return Object::IsHeapObject() && \
73 HeapObject::cast(this)->map()->instance_type() == instancetype; \
74 }
75
76
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000077#define CAST_ACCESSOR(type) \
78 type* type::cast(Object* object) { \
79 ASSERT(object->Is##type()); \
80 return reinterpret_cast<type*>(object); \
81 }
82
83
84#define INT_ACCESSORS(holder, name, offset) \
85 int holder::name() { return READ_INT_FIELD(this, offset); } \
86 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
87
88
89#define ACCESSORS(holder, name, type, offset) \
90 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000091 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000092 WRITE_FIELD(this, offset, value); \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000093 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000094 }
95
96
rossberg@chromium.org2c067b12012-03-19 11:01:52 +000097// Getter that returns a tagged Smi and setter that writes a tagged Smi.
98#define ACCESSORS_TO_SMI(holder, name, offset) \
99 Smi* holder::name() { return Smi::cast(READ_FIELD(this, offset)); } \
100 void holder::set_##name(Smi* value, WriteBarrierMode mode) { \
101 WRITE_FIELD(this, offset, value); \
102 }
103
104
105// Getter that returns a Smi as an int and writes an int as a Smi.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000106#define SMI_ACCESSORS(holder, name, offset) \
107 int holder::name() { \
108 Object* value = READ_FIELD(this, offset); \
109 return Smi::cast(value)->value(); \
110 } \
111 void holder::set_##name(int value) { \
112 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
113 }
114
115
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000116#define BOOL_GETTER(holder, field, name, offset) \
117 bool holder::name() { \
118 return BooleanBit::get(field(), offset); \
119 } \
120
121
122#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000123 bool holder::name() { \
124 return BooleanBit::get(field(), offset); \
125 } \
126 void holder::set_##name(bool value) { \
127 set_##field(BooleanBit::set(field(), offset, value)); \
128 }
129
130
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000131bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
132 ElementsKind to_kind) {
133 if (to_kind == FAST_ELEMENTS) {
134 return from_kind == FAST_SMI_ONLY_ELEMENTS ||
135 from_kind == FAST_DOUBLE_ELEMENTS;
136 } else {
137 return to_kind == FAST_DOUBLE_ELEMENTS &&
138 from_kind == FAST_SMI_ONLY_ELEMENTS;
139 }
140}
141
142
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000143bool Object::IsFixedArrayBase() {
144 return IsFixedArray() || IsFixedDoubleArray();
145}
146
147
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000148bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
149 // There is a constraint on the object; check.
150 if (!this->IsJSObject()) return false;
151 // Fetch the constructor function of the object.
152 Object* cons_obj = JSObject::cast(this)->map()->constructor();
153 if (!cons_obj->IsJSFunction()) return false;
154 JSFunction* fun = JSFunction::cast(cons_obj);
155 // Iterate through the chain of inheriting function templates to
156 // see if the required one occurs.
157 for (Object* type = fun->shared()->function_data();
158 type->IsFunctionTemplateInfo();
159 type = FunctionTemplateInfo::cast(type)->parent_template()) {
160 if (type == expected) return true;
161 }
162 // Didn't find the required type in the inheritance chain.
163 return false;
164}
165
166
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000167bool Object::IsSmi() {
168 return HAS_SMI_TAG(this);
169}
170
171
172bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000173 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000174}
175
176
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000177bool Object::NonFailureIsHeapObject() {
178 ASSERT(!this->IsFailure());
179 return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0;
180}
181
182
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000183TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000184
185
186bool Object::IsString() {
187 return Object::IsHeapObject()
188 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
189}
190
191
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000192bool Object::IsSpecObject() {
193 return Object::IsHeapObject()
194 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
195}
196
197
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000198bool Object::IsSpecFunction() {
199 if (!Object::IsHeapObject()) return false;
200 InstanceType type = HeapObject::cast(this)->map()->instance_type();
201 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
202}
203
204
ager@chromium.org870a0b62008-11-04 11:43:05 +0000205bool Object::IsSymbol() {
206 if (!this->IsHeapObject()) return false;
207 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000208 // Because the symbol tag is non-zero and no non-string types have the
209 // symbol bit set we can test for symbols with a very simple test
210 // operation.
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000211 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000212 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
213 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000214}
215
216
217bool Object::IsConsString() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000218 if (!IsString()) return false;
219 return StringShape(String::cast(this)).IsCons();
220}
221
222
223bool Object::IsSlicedString() {
224 if (!IsString()) return false;
225 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000226}
227
228
ager@chromium.org870a0b62008-11-04 11:43:05 +0000229bool Object::IsSeqString() {
230 if (!IsString()) return false;
231 return StringShape(String::cast(this)).IsSequential();
232}
233
234
235bool Object::IsSeqAsciiString() {
236 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000237 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000238 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000239}
240
241
242bool Object::IsSeqTwoByteString() {
243 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000244 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000245 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000246}
247
248
249bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000250 if (!IsString()) return false;
251 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000252}
253
254
255bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000256 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000257 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000258 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000259}
260
261
262bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000263 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000264 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000265 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000266}
267
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000268bool Object::HasValidElements() {
269 // Dictionary is covered under FixedArray.
270 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
271}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000272
ager@chromium.org870a0b62008-11-04 11:43:05 +0000273StringShape::StringShape(String* str)
274 : type_(str->map()->instance_type()) {
275 set_valid();
276 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000277}
278
279
ager@chromium.org870a0b62008-11-04 11:43:05 +0000280StringShape::StringShape(Map* map)
281 : type_(map->instance_type()) {
282 set_valid();
283 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000284}
285
286
ager@chromium.org870a0b62008-11-04 11:43:05 +0000287StringShape::StringShape(InstanceType t)
288 : type_(static_cast<uint32_t>(t)) {
289 set_valid();
290 ASSERT((type_ & kIsNotStringMask) == kStringTag);
291}
292
293
294bool StringShape::IsSymbol() {
295 ASSERT(valid());
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000296 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000297 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000298}
299
300
ager@chromium.org5ec48922009-05-05 07:25:34 +0000301bool String::IsAsciiRepresentation() {
302 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000303 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000304}
305
306
ager@chromium.org5ec48922009-05-05 07:25:34 +0000307bool String::IsTwoByteRepresentation() {
308 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000309 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000310}
311
312
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000313bool String::IsAsciiRepresentationUnderneath() {
314 uint32_t type = map()->instance_type();
315 STATIC_ASSERT(kIsIndirectStringTag != 0);
316 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
317 ASSERT(IsFlat());
318 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
319 case kAsciiStringTag:
320 return true;
321 case kTwoByteStringTag:
322 return false;
323 default: // Cons or sliced string. Need to go deeper.
324 return GetUnderlying()->IsAsciiRepresentation();
325 }
326}
327
328
329bool String::IsTwoByteRepresentationUnderneath() {
330 uint32_t type = map()->instance_type();
331 STATIC_ASSERT(kIsIndirectStringTag != 0);
332 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
333 ASSERT(IsFlat());
334 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
335 case kAsciiStringTag:
336 return false;
337 case kTwoByteStringTag:
338 return true;
339 default: // Cons or sliced string. Need to go deeper.
340 return GetUnderlying()->IsTwoByteRepresentation();
341 }
342}
343
344
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000345bool String::HasOnlyAsciiChars() {
346 uint32_t type = map()->instance_type();
347 return (type & kStringEncodingMask) == kAsciiStringTag ||
348 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000349}
350
351
ager@chromium.org870a0b62008-11-04 11:43:05 +0000352bool StringShape::IsCons() {
353 return (type_ & kStringRepresentationMask) == kConsStringTag;
354}
355
356
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000357bool StringShape::IsSliced() {
358 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
359}
360
361
362bool StringShape::IsIndirect() {
363 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
364}
365
366
ager@chromium.org870a0b62008-11-04 11:43:05 +0000367bool StringShape::IsExternal() {
368 return (type_ & kStringRepresentationMask) == kExternalStringTag;
369}
370
371
372bool StringShape::IsSequential() {
373 return (type_ & kStringRepresentationMask) == kSeqStringTag;
374}
375
376
377StringRepresentationTag StringShape::representation_tag() {
378 uint32_t tag = (type_ & kStringRepresentationMask);
379 return static_cast<StringRepresentationTag>(tag);
380}
381
382
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000383uint32_t StringShape::encoding_tag() {
384 return type_ & kStringEncodingMask;
385}
386
387
ager@chromium.org870a0b62008-11-04 11:43:05 +0000388uint32_t StringShape::full_representation_tag() {
389 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
390}
391
392
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000393STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
394 Internals::kFullStringRepresentationMask);
395
396
ager@chromium.org870a0b62008-11-04 11:43:05 +0000397bool StringShape::IsSequentialAscii() {
398 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
399}
400
401
402bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000403 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000404}
405
406
407bool StringShape::IsExternalAscii() {
408 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
409}
410
411
412bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000413 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000414}
415
416
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000417STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
418 Internals::kExternalTwoByteRepresentationTag);
419
420
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000421uc32 FlatStringReader::Get(int index) {
422 ASSERT(0 <= index && index <= length_);
423 if (is_ascii_) {
424 return static_cast<const byte*>(start_)[index];
425 } else {
426 return static_cast<const uc16*>(start_)[index];
427 }
428}
429
430
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000431bool Object::IsNumber() {
432 return IsSmi() || IsHeapNumber();
433}
434
435
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000436TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
437TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000438
439
440bool Object::IsFiller() {
441 if (!Object::IsHeapObject()) return false;
442 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
443 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
444}
445
446
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000447TYPE_CHECKER(ExternalPixelArray, EXTERNAL_PIXEL_ARRAY_TYPE)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000448
449
ager@chromium.org3811b432009-10-28 14:53:37 +0000450bool Object::IsExternalArray() {
451 if (!Object::IsHeapObject())
452 return false;
453 InstanceType instance_type =
454 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000455 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
456 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000457}
458
459
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000460TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE)
461TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
462TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE)
463TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
464TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE)
465TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
466TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE)
467TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000468
469
lrn@chromium.org303ada72010-10-27 09:33:13 +0000470bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000471 return HAS_FAILURE_TAG(this);
472}
473
474
lrn@chromium.org303ada72010-10-27 09:33:13 +0000475bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000476 return HAS_FAILURE_TAG(this)
477 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
478}
479
480
lrn@chromium.org303ada72010-10-27 09:33:13 +0000481bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000482 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000483 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000484}
485
486
lrn@chromium.org303ada72010-10-27 09:33:13 +0000487bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000488 return this == Failure::Exception();
489}
490
491
lrn@chromium.org303ada72010-10-27 09:33:13 +0000492bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000493 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000494}
495
496
497Failure* Failure::cast(MaybeObject* obj) {
498 ASSERT(HAS_FAILURE_TAG(obj));
499 return reinterpret_cast<Failure*>(obj);
500}
501
502
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000503bool Object::IsJSReceiver() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000504 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000505 return IsHeapObject() &&
506 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
507}
508
509
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000510bool Object::IsJSObject() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000511 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
512 return IsHeapObject() &&
513 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000514}
515
516
517bool Object::IsJSProxy() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000518 if (!Object::IsHeapObject()) return false;
519 InstanceType type = HeapObject::cast(this)->map()->instance_type();
520 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000521}
522
523
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000524TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
525TYPE_CHECKER(JSSet, JS_SET_TYPE)
526TYPE_CHECKER(JSMap, JS_MAP_TYPE)
527TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
528TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
529TYPE_CHECKER(Map, MAP_TYPE)
530TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
531TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000532
533
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000534bool Object::IsDescriptorArray() {
535 return IsFixedArray();
536}
537
538
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000539bool Object::IsDeoptimizationInputData() {
540 // Must be a fixed array.
541 if (!IsFixedArray()) return false;
542
543 // There's no sure way to detect the difference between a fixed array and
544 // a deoptimization data array. Since this is used for asserts we can
545 // check that the length is zero or else the fixed size plus a multiple of
546 // the entry size.
547 int length = FixedArray::cast(this)->length();
548 if (length == 0) return true;
549
550 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
551 return length >= 0 &&
552 length % DeoptimizationInputData::kDeoptEntrySize == 0;
553}
554
555
556bool Object::IsDeoptimizationOutputData() {
557 if (!IsFixedArray()) return false;
558 // There's actually no way to see the difference between a fixed array and
559 // a deoptimization data array. Since this is used for asserts we can check
560 // that the length is plausible though.
561 if (FixedArray::cast(this)->length() % 2 != 0) return false;
562 return true;
563}
564
565
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000566bool Object::IsTypeFeedbackCells() {
567 if (!IsFixedArray()) return false;
568 // There's actually no way to see the difference between a fixed array and
569 // a cache cells array. Since this is used for asserts we can check that
570 // the length is plausible though.
571 if (FixedArray::cast(this)->length() % 2 != 0) return false;
572 return true;
573}
574
575
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000576bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000577 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000578 Map* map = HeapObject::cast(this)->map();
579 Heap* heap = map->GetHeap();
580 return (map == heap->function_context_map() ||
581 map == heap->catch_context_map() ||
582 map == heap->with_context_map() ||
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000583 map == heap->global_context_map() ||
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000584 map == heap->block_context_map() ||
585 map == heap->module_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000586 }
587 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000588}
589
590
591bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000592 return Object::IsHeapObject() &&
593 HeapObject::cast(this)->map() ==
594 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000595}
596
597
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000598bool Object::IsModuleContext() {
599 return Object::IsHeapObject() &&
600 HeapObject::cast(this)->map() ==
601 HeapObject::cast(this)->GetHeap()->module_context_map();
602}
603
604
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000605bool Object::IsScopeInfo() {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000606 return Object::IsHeapObject() &&
607 HeapObject::cast(this)->map() ==
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000608 HeapObject::cast(this)->GetHeap()->scope_info_map();
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000609}
610
611
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000612TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000613
614
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000615template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000616 return obj->IsJSFunction();
617}
618
619
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000620TYPE_CHECKER(Code, CODE_TYPE)
621TYPE_CHECKER(Oddball, ODDBALL_TYPE)
622TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
623TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000624TYPE_CHECKER(JSModule, JS_MODULE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000625TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000626TYPE_CHECKER(JSDate, JS_DATE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000627TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000628
629
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000630bool Object::IsStringWrapper() {
631 return IsJSValue() && JSValue::cast(this)->value()->IsString();
632}
633
634
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000635TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000636
637
638bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000639 return IsOddball() &&
640 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000641}
642
643
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000644TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
645TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000646
647
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000648template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000649 return obj->IsJSArray();
650}
651
652
653bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000654 return Object::IsHeapObject() &&
655 HeapObject::cast(this)->map() ==
656 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000657}
658
659
660bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000661 return IsHashTable() &&
662 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000663}
664
665
666bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000667 return IsHashTable() && this ==
668 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000669}
670
671
ager@chromium.orgac091b72010-05-05 07:34:42 +0000672bool Object::IsJSFunctionResultCache() {
673 if (!IsFixedArray()) return false;
674 FixedArray* self = FixedArray::cast(this);
675 int length = self->length();
676 if (length < JSFunctionResultCache::kEntriesIndex) return false;
677 if ((length - JSFunctionResultCache::kEntriesIndex)
678 % JSFunctionResultCache::kEntrySize != 0) {
679 return false;
680 }
681#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000682 if (FLAG_verify_heap) {
683 reinterpret_cast<JSFunctionResultCache*>(this)->
684 JSFunctionResultCacheVerify();
685 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000686#endif
687 return true;
688}
689
690
ricow@chromium.org65fae842010-08-25 15:26:24 +0000691bool Object::IsNormalizedMapCache() {
692 if (!IsFixedArray()) return false;
693 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
694 return false;
695 }
696#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000697 if (FLAG_verify_heap) {
698 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
699 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000700#endif
701 return true;
702}
703
704
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000705bool Object::IsCompilationCacheTable() {
706 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000707}
708
709
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000710bool Object::IsCodeCacheHashTable() {
711 return IsHashTable();
712}
713
714
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000715bool Object::IsPolymorphicCodeCacheHashTable() {
716 return IsHashTable();
717}
718
719
ager@chromium.org236ad962008-09-25 09:45:57 +0000720bool Object::IsMapCache() {
721 return IsHashTable();
722}
723
724
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000725bool Object::IsPrimitive() {
726 return IsOddball() || IsNumber() || IsString();
727}
728
729
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000730bool Object::IsJSGlobalProxy() {
731 bool result = IsHeapObject() &&
732 (HeapObject::cast(this)->map()->instance_type() ==
733 JS_GLOBAL_PROXY_TYPE);
734 ASSERT(!result || IsAccessCheckNeeded());
735 return result;
736}
737
738
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000739bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000740 if (!IsHeapObject()) return false;
741
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000742 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000743 return type == JS_GLOBAL_OBJECT_TYPE ||
744 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000745}
746
747
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000748TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
749TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000750
751
752bool Object::IsUndetectableObject() {
753 return IsHeapObject()
754 && HeapObject::cast(this)->map()->is_undetectable();
755}
756
757
758bool Object::IsAccessCheckNeeded() {
759 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000760 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000761}
762
763
764bool Object::IsStruct() {
765 if (!IsHeapObject()) return false;
766 switch (HeapObject::cast(this)->map()->instance_type()) {
767#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
768 STRUCT_LIST(MAKE_STRUCT_CASE)
769#undef MAKE_STRUCT_CASE
770 default: return false;
771 }
772}
773
774
775#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
776 bool Object::Is##Name() { \
777 return Object::IsHeapObject() \
778 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
779 }
780 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
781#undef MAKE_STRUCT_PREDICATE
782
783
784bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000785 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000786}
787
788
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000789bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000790 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
791}
792
793
794bool Object::IsTheHole() {
795 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000796}
797
798
799bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000800 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000801}
802
803
804bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000805 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000806}
807
808
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000809bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000810 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000811}
812
813
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000814double Object::Number() {
815 ASSERT(IsNumber());
816 return IsSmi()
817 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
818 : reinterpret_cast<HeapNumber*>(this)->value();
819}
820
821
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000822bool Object::IsNaN() {
823 return this->IsHeapNumber() && isnan(HeapNumber::cast(this)->value());
824}
825
826
lrn@chromium.org303ada72010-10-27 09:33:13 +0000827MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000828 if (IsSmi()) return this;
829 if (IsHeapNumber()) {
830 double value = HeapNumber::cast(this)->value();
831 int int_value = FastD2I(value);
832 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
833 return Smi::FromInt(int_value);
834 }
835 }
836 return Failure::Exception();
837}
838
839
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000840bool Object::HasSpecificClassOf(String* name) {
841 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
842}
843
844
lrn@chromium.org303ada72010-10-27 09:33:13 +0000845MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000846 // GetElement can trigger a getter which can cause allocation.
847 // This was not always the case. This ASSERT is here to catch
848 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000849 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000850 return GetElementWithReceiver(this, index);
851}
852
853
lrn@chromium.org303ada72010-10-27 09:33:13 +0000854Object* Object::GetElementNoExceptionThrown(uint32_t index) {
855 MaybeObject* maybe = GetElementWithReceiver(this, index);
856 ASSERT(!maybe->IsFailure());
857 Object* result = NULL; // Initialization to please compiler.
858 maybe->ToObject(&result);
859 return result;
860}
861
862
863MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000864 PropertyAttributes attributes;
865 return GetPropertyWithReceiver(this, key, &attributes);
866}
867
868
lrn@chromium.org303ada72010-10-27 09:33:13 +0000869MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000870 return GetPropertyWithReceiver(this, key, attributes);
871}
872
873
874#define FIELD_ADDR(p, offset) \
875 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
876
877#define READ_FIELD(p, offset) \
878 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
879
880#define WRITE_FIELD(p, offset, value) \
881 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
882
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000883#define WRITE_BARRIER(heap, object, offset, value) \
884 heap->incremental_marking()->RecordWrite( \
885 object, HeapObject::RawField(object, offset), value); \
886 if (heap->InNewSpace(value)) { \
887 heap->RecordWrite(object->address(), offset); \
888 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000889
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000890#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
891 if (mode == UPDATE_WRITE_BARRIER) { \
892 heap->incremental_marking()->RecordWrite( \
893 object, HeapObject::RawField(object, offset), value); \
894 if (heap->InNewSpace(value)) { \
895 heap->RecordWrite(object->address(), offset); \
896 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000897 }
898
lrn@chromium.org7516f052011-03-30 08:52:27 +0000899#ifndef V8_TARGET_ARCH_MIPS
900 #define READ_DOUBLE_FIELD(p, offset) \
901 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
902#else // V8_TARGET_ARCH_MIPS
903 // Prevent gcc from using load-double (mips ldc1) on (possibly)
904 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000905 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000906 union conversion {
907 double d;
908 uint32_t u[2];
909 } c;
910 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
911 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
912 return c.d;
913 }
914 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
915#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000916
lrn@chromium.org7516f052011-03-30 08:52:27 +0000917#ifndef V8_TARGET_ARCH_MIPS
918 #define WRITE_DOUBLE_FIELD(p, offset, value) \
919 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
920#else // V8_TARGET_ARCH_MIPS
921 // Prevent gcc from using store-double (mips sdc1) on (possibly)
922 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000923 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000924 double value) {
925 union conversion {
926 double d;
927 uint32_t u[2];
928 } c;
929 c.d = value;
930 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
931 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
932 }
933 #define WRITE_DOUBLE_FIELD(p, offset, value) \
934 write_double_field(p, offset, value)
935#endif // V8_TARGET_ARCH_MIPS
936
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000937
938#define READ_INT_FIELD(p, offset) \
939 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
940
941#define WRITE_INT_FIELD(p, offset, value) \
942 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
943
ager@chromium.org3e875802009-06-29 08:26:34 +0000944#define READ_INTPTR_FIELD(p, offset) \
945 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
946
947#define WRITE_INTPTR_FIELD(p, offset, value) \
948 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
949
ager@chromium.org7c537e22008-10-16 08:43:32 +0000950#define READ_UINT32_FIELD(p, offset) \
951 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
952
953#define WRITE_UINT32_FIELD(p, offset, value) \
954 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
955
danno@chromium.org88aa0582012-03-23 15:11:57 +0000956#define READ_INT64_FIELD(p, offset) \
957 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)))
958
959#define WRITE_INT64_FIELD(p, offset, value) \
960 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
961
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000962#define READ_SHORT_FIELD(p, offset) \
963 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
964
965#define WRITE_SHORT_FIELD(p, offset, value) \
966 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
967
968#define READ_BYTE_FIELD(p, offset) \
969 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
970
971#define WRITE_BYTE_FIELD(p, offset, value) \
972 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
973
974
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000975Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
976 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000977}
978
979
980int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000981 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000982}
983
984
985Smi* Smi::FromInt(int value) {
986 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000987 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000988 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000989 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000990 return reinterpret_cast<Smi*>(tagged_value);
991}
992
993
994Smi* Smi::FromIntptr(intptr_t value) {
995 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000996 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
997 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000998}
999
1000
1001Failure::Type Failure::type() const {
1002 return static_cast<Type>(value() & kFailureTypeTagMask);
1003}
1004
1005
1006bool Failure::IsInternalError() const {
1007 return type() == INTERNAL_ERROR;
1008}
1009
1010
1011bool Failure::IsOutOfMemoryException() const {
1012 return type() == OUT_OF_MEMORY_EXCEPTION;
1013}
1014
1015
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001016AllocationSpace Failure::allocation_space() const {
1017 ASSERT_EQ(RETRY_AFTER_GC, type());
1018 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1019 & kSpaceTagMask);
1020}
1021
1022
1023Failure* Failure::InternalError() {
1024 return Construct(INTERNAL_ERROR);
1025}
1026
1027
1028Failure* Failure::Exception() {
1029 return Construct(EXCEPTION);
1030}
1031
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001032
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001033Failure* Failure::OutOfMemoryException() {
1034 return Construct(OUT_OF_MEMORY_EXCEPTION);
1035}
1036
1037
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001038intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001039 return static_cast<intptr_t>(
1040 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001041}
1042
1043
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001044Failure* Failure::RetryAfterGC() {
1045 return RetryAfterGC(NEW_SPACE);
1046}
1047
1048
1049Failure* Failure::RetryAfterGC(AllocationSpace space) {
1050 ASSERT((space & ~kSpaceTagMask) == 0);
1051 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001052}
1053
1054
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001055Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001056 uintptr_t info =
1057 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001058 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001059 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001060}
1061
1062
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001063bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001064#ifdef DEBUG
1065 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1066#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001067
1068#ifdef V8_TARGET_ARCH_X64
1069 // To be representable as a long smi, the value must be a 32-bit integer.
1070 bool result = (value == static_cast<int32_t>(value));
1071#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001072 // To be representable as an tagged small integer, the two
1073 // most-significant bits of 'value' must be either 00 or 11 due to
1074 // sign-extension. To check this we add 01 to the two
1075 // most-significant bits, and check if the most-significant bit is 0
1076 //
1077 // CAUTION: The original code below:
1078 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1079 // may lead to incorrect results according to the C language spec, and
1080 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1081 // compiler may produce undefined results in case of signed integer
1082 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001083 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001084#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001085 ASSERT(result == in_range);
1086 return result;
1087}
1088
1089
kasper.lund7276f142008-07-30 08:49:36 +00001090MapWord MapWord::FromMap(Map* map) {
1091 return MapWord(reinterpret_cast<uintptr_t>(map));
1092}
1093
1094
1095Map* MapWord::ToMap() {
1096 return reinterpret_cast<Map*>(value_);
1097}
1098
1099
1100bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001101 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001102}
1103
1104
1105MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001106 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1107 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001108}
1109
1110
1111HeapObject* MapWord::ToForwardingAddress() {
1112 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001113 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001114}
1115
1116
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001117#ifdef DEBUG
1118void HeapObject::VerifyObjectField(int offset) {
1119 VerifyPointer(READ_FIELD(this, offset));
1120}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001121
1122void HeapObject::VerifySmiField(int offset) {
1123 ASSERT(READ_FIELD(this, offset)->IsSmi());
1124}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001125#endif
1126
1127
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001128Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001129 Heap* heap =
1130 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1131 ASSERT(heap != NULL);
1132 ASSERT(heap->isolate() == Isolate::Current());
1133 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001134}
1135
1136
1137Isolate* HeapObject::GetIsolate() {
1138 return GetHeap()->isolate();
1139}
1140
1141
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001142Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001143 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001144}
1145
1146
1147void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001148 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001149 if (value != NULL) {
1150 // TODO(1600) We are passing NULL as a slot because maps can never be on
1151 // evacuation candidate.
1152 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1153 }
1154}
1155
1156
1157// Unsafe accessor omitting write barrier.
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001158void HeapObject::set_map_no_write_barrier(Map* value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001159 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001160}
1161
1162
kasper.lund7276f142008-07-30 08:49:36 +00001163MapWord HeapObject::map_word() {
1164 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1165}
1166
1167
1168void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001169 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001170 // here.
1171 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1172}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001173
1174
1175HeapObject* HeapObject::FromAddress(Address address) {
1176 ASSERT_TAG_ALIGNED(address);
1177 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1178}
1179
1180
1181Address HeapObject::address() {
1182 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1183}
1184
1185
1186int HeapObject::Size() {
1187 return SizeFromMap(map());
1188}
1189
1190
1191void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1192 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1193 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1194}
1195
1196
1197void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1198 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1199}
1200
1201
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001202double HeapNumber::value() {
1203 return READ_DOUBLE_FIELD(this, kValueOffset);
1204}
1205
1206
1207void HeapNumber::set_value(double value) {
1208 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1209}
1210
1211
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001212int HeapNumber::get_exponent() {
1213 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1214 kExponentShift) - kExponentBias;
1215}
1216
1217
1218int HeapNumber::get_sign() {
1219 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1220}
1221
1222
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001223ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001224
1225
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001226Object** FixedArray::GetFirstElementAddress() {
1227 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1228}
1229
1230
1231bool FixedArray::ContainsOnlySmisOrHoles() {
1232 Object* the_hole = GetHeap()->the_hole_value();
1233 Object** current = GetFirstElementAddress();
1234 for (int i = 0; i < length(); ++i) {
1235 Object* candidate = *current++;
1236 if (!candidate->IsSmi() && candidate != the_hole) return false;
1237 }
1238 return true;
1239}
1240
1241
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001242FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001243 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001244 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001245}
1246
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001247void JSObject::ValidateSmiOnlyElements() {
1248#if DEBUG
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001249 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001250 Heap* heap = GetHeap();
1251 // Don't use elements, since integrity checks will fail if there
1252 // are filler pointers in the array.
1253 FixedArray* fixed_array =
1254 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
1255 Map* map = fixed_array->map();
1256 // Arrays that have been shifted in place can't be verified.
1257 if (map != heap->raw_unchecked_one_pointer_filler_map() &&
1258 map != heap->raw_unchecked_two_pointer_filler_map() &&
1259 map != heap->free_space_map()) {
1260 for (int i = 0; i < fixed_array->length(); i++) {
1261 Object* current = fixed_array->get(i);
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001262 ASSERT(current->IsSmi() || current->IsTheHole());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001263 }
1264 }
1265 }
1266#endif
1267}
1268
1269
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001270MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001271#if DEBUG
1272 ValidateSmiOnlyElements();
1273#endif
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001274 if ((map()->elements_kind() != FAST_ELEMENTS)) {
1275 return TransitionElementsKind(FAST_ELEMENTS);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001276 }
1277 return this;
1278}
1279
1280
1281MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001282 uint32_t count,
1283 EnsureElementsMode mode) {
1284 ElementsKind current_kind = map()->elements_kind();
1285 ElementsKind target_kind = current_kind;
1286 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
1287 if (current_kind == FAST_ELEMENTS) return this;
1288
1289 Heap* heap = GetHeap();
1290 Object* the_hole = heap->the_hole_value();
1291 Object* heap_number_map = heap->heap_number_map();
1292 for (uint32_t i = 0; i < count; ++i) {
1293 Object* current = *objects++;
1294 if (!current->IsSmi() && current != the_hole) {
1295 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS &&
1296 HeapObject::cast(current)->map() == heap_number_map) {
1297 target_kind = FAST_DOUBLE_ELEMENTS;
1298 } else {
1299 target_kind = FAST_ELEMENTS;
1300 break;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001301 }
1302 }
1303 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001304
1305 if (target_kind != current_kind) {
1306 return TransitionElementsKind(target_kind);
1307 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001308 return this;
1309}
1310
1311
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001312MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
1313 EnsureElementsMode mode) {
1314 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1315 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1316 elements->map() == GetHeap()->fixed_cow_array_map());
1317 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1318 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1319 }
1320 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
1321 return EnsureCanContainElements(objects, elements->length(), mode);
1322 }
1323
1324 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
1325 if (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) {
1326 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1327 }
1328
1329 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001330}
1331
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001332
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001333MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
1334 ElementsKind to_kind) {
1335 Map* current_map = map();
1336 ElementsKind from_kind = current_map->elements_kind();
1337
1338 if (from_kind == to_kind) return current_map;
1339
1340 Context* global_context = isolate->context()->global_context();
1341 if (current_map == global_context->smi_js_array_map()) {
1342 if (to_kind == FAST_ELEMENTS) {
1343 return global_context->object_js_array_map();
1344 } else {
1345 if (to_kind == FAST_DOUBLE_ELEMENTS) {
1346 return global_context->double_js_array_map();
1347 } else {
1348 ASSERT(to_kind == DICTIONARY_ELEMENTS);
1349 }
1350 }
1351 }
1352 return GetElementsTransitionMapSlow(to_kind);
1353}
1354
1355
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001356void JSObject::set_map_and_elements(Map* new_map,
1357 FixedArrayBase* value,
1358 WriteBarrierMode mode) {
1359 ASSERT(value->HasValidElements());
1360#ifdef DEBUG
1361 ValidateSmiOnlyElements();
1362#endif
1363 if (new_map != NULL) {
1364 if (mode == UPDATE_WRITE_BARRIER) {
1365 set_map(new_map);
1366 } else {
1367 ASSERT(mode == SKIP_WRITE_BARRIER);
1368 set_map_no_write_barrier(new_map);
1369 }
1370 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001371 ASSERT((map()->has_fast_elements() ||
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001372 map()->has_fast_smi_only_elements() ||
1373 (value == GetHeap()->empty_fixed_array())) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001374 (value->map() == GetHeap()->fixed_array_map() ||
1375 value->map() == GetHeap()->fixed_cow_array_map()));
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001376 ASSERT((value == GetHeap()->empty_fixed_array()) ||
1377 (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001378 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001379 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001380}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001381
1382
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001383void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1384 set_map_and_elements(NULL, value, mode);
1385}
1386
1387
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001388void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001389 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1390 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001391}
1392
1393
1394void JSObject::initialize_elements() {
danno@chromium.org2c26cb12012-05-03 09:06:43 +00001395 ASSERT(map()->has_fast_elements() ||
1396 map()->has_fast_smi_only_elements() ||
1397 map()->has_fast_double_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001398 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1399 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001400}
1401
1402
lrn@chromium.org303ada72010-10-27 09:33:13 +00001403MaybeObject* JSObject::ResetElements() {
1404 Object* obj;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001405 ElementsKind elements_kind = FLAG_smi_only_arrays
1406 ? FAST_SMI_ONLY_ELEMENTS
1407 : FAST_ELEMENTS;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001408 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(),
1409 elements_kind);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001410 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001411 set_map(Map::cast(obj));
1412 initialize_elements();
1413 return this;
1414}
1415
1416
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001417ACCESSORS(Oddball, to_string, String, kToStringOffset)
1418ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1419
1420
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001421byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001422 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001423}
1424
1425
1426void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001427 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001428}
1429
1430
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001431Object* JSGlobalPropertyCell::value() {
1432 return READ_FIELD(this, kValueOffset);
1433}
1434
1435
1436void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1437 // The write barrier is not used for global property cells.
1438 ASSERT(!val->IsJSGlobalPropertyCell());
1439 WRITE_FIELD(this, kValueOffset, val);
1440}
1441
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001442
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001443int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001444 InstanceType type = map()->instance_type();
1445 // Check for the most common kind of JavaScript object before
1446 // falling into the generic switch. This speeds up the internal
1447 // field operations considerably on average.
1448 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1449 switch (type) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001450 case JS_MODULE_TYPE:
1451 return JSModule::kSize;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001452 case JS_GLOBAL_PROXY_TYPE:
1453 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001454 case JS_GLOBAL_OBJECT_TYPE:
1455 return JSGlobalObject::kSize;
1456 case JS_BUILTINS_OBJECT_TYPE:
1457 return JSBuiltinsObject::kSize;
1458 case JS_FUNCTION_TYPE:
1459 return JSFunction::kSize;
1460 case JS_VALUE_TYPE:
1461 return JSValue::kSize;
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00001462 case JS_DATE_TYPE:
1463 return JSDate::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001464 case JS_ARRAY_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001465 return JSArray::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001466 case JS_WEAK_MAP_TYPE:
1467 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001468 case JS_REGEXP_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001469 return JSRegExp::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001470 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001471 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001472 case JS_MESSAGE_OBJECT_TYPE:
1473 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001474 default:
1475 UNREACHABLE();
1476 return 0;
1477 }
1478}
1479
1480
1481int JSObject::GetInternalFieldCount() {
1482 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001483 // Make sure to adjust for the number of in-object properties. These
1484 // properties do contribute to the size, but are not internal fields.
1485 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1486 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001487}
1488
1489
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001490int JSObject::GetInternalFieldOffset(int index) {
1491 ASSERT(index < GetInternalFieldCount() && index >= 0);
1492 return GetHeaderSize() + (kPointerSize * index);
1493}
1494
1495
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001496Object* JSObject::GetInternalField(int index) {
1497 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001498 // Internal objects do follow immediately after the header, whereas in-object
1499 // properties are at the end of the object. Therefore there is no need
1500 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001501 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1502}
1503
1504
1505void JSObject::SetInternalField(int index, Object* value) {
1506 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001507 // Internal objects do follow immediately after the header, whereas in-object
1508 // properties are at the end of the object. Therefore there is no need
1509 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001510 int offset = GetHeaderSize() + (kPointerSize * index);
1511 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001512 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001513}
1514
1515
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001516void JSObject::SetInternalField(int index, Smi* value) {
1517 ASSERT(index < GetInternalFieldCount() && index >= 0);
1518 // Internal objects do follow immediately after the header, whereas in-object
1519 // properties are at the end of the object. Therefore there is no need
1520 // to adjust the index here.
1521 int offset = GetHeaderSize() + (kPointerSize * index);
1522 WRITE_FIELD(this, offset, value);
1523}
1524
1525
ager@chromium.org7c537e22008-10-16 08:43:32 +00001526// Access fast-case object properties at index. The use of these routines
1527// is needed to correctly distinguish between properties stored in-object and
1528// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001529Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001530 // Adjust for the number of properties stored in the object.
1531 index -= map()->inobject_properties();
1532 if (index < 0) {
1533 int offset = map()->instance_size() + (index * kPointerSize);
1534 return READ_FIELD(this, offset);
1535 } else {
1536 ASSERT(index < properties()->length());
1537 return properties()->get(index);
1538 }
1539}
1540
1541
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001542Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001543 // Adjust for the number of properties stored in the object.
1544 index -= map()->inobject_properties();
1545 if (index < 0) {
1546 int offset = map()->instance_size() + (index * kPointerSize);
1547 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001548 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001549 } else {
1550 ASSERT(index < properties()->length());
1551 properties()->set(index, value);
1552 }
1553 return value;
1554}
1555
1556
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001557int JSObject::GetInObjectPropertyOffset(int index) {
1558 // Adjust for the number of properties stored in the object.
1559 index -= map()->inobject_properties();
1560 ASSERT(index < 0);
1561 return map()->instance_size() + (index * kPointerSize);
1562}
1563
1564
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001565Object* JSObject::InObjectPropertyAt(int index) {
1566 // Adjust for the number of properties stored in the object.
1567 index -= map()->inobject_properties();
1568 ASSERT(index < 0);
1569 int offset = map()->instance_size() + (index * kPointerSize);
1570 return READ_FIELD(this, offset);
1571}
1572
1573
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001574Object* JSObject::InObjectPropertyAtPut(int index,
1575 Object* value,
1576 WriteBarrierMode mode) {
1577 // Adjust for the number of properties stored in the object.
1578 index -= map()->inobject_properties();
1579 ASSERT(index < 0);
1580 int offset = map()->instance_size() + (index * kPointerSize);
1581 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001582 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001583 return value;
1584}
1585
1586
1587
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001588void JSObject::InitializeBody(Map* map,
1589 Object* pre_allocated_value,
1590 Object* filler_value) {
1591 ASSERT(!filler_value->IsHeapObject() ||
1592 !GetHeap()->InNewSpace(filler_value));
1593 ASSERT(!pre_allocated_value->IsHeapObject() ||
1594 !GetHeap()->InNewSpace(pre_allocated_value));
1595 int size = map->instance_size();
1596 int offset = kHeaderSize;
1597 if (filler_value != pre_allocated_value) {
1598 int pre_allocated = map->pre_allocated_property_fields();
1599 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1600 for (int i = 0; i < pre_allocated; i++) {
1601 WRITE_FIELD(this, offset, pre_allocated_value);
1602 offset += kPointerSize;
1603 }
1604 }
1605 while (offset < size) {
1606 WRITE_FIELD(this, offset, filler_value);
1607 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001608 }
1609}
1610
1611
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001612bool JSObject::HasFastProperties() {
1613 return !properties()->IsDictionary();
1614}
1615
1616
1617int JSObject::MaxFastProperties() {
1618 // Allow extra fast properties if the object has more than
1619 // kMaxFastProperties in-object properties. When this is the case,
1620 // it is very unlikely that the object is being used as a dictionary
1621 // and there is a good chance that allowing more map transitions
1622 // will be worth it.
1623 return Max(map()->inobject_properties(), kMaxFastProperties);
1624}
1625
1626
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001627void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001628 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001629 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001630 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001631 }
1632}
1633
1634
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001635bool Object::ToArrayIndex(uint32_t* index) {
1636 if (IsSmi()) {
1637 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001638 if (value < 0) return false;
1639 *index = value;
1640 return true;
1641 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001642 if (IsHeapNumber()) {
1643 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001644 uint32_t uint_value = static_cast<uint32_t>(value);
1645 if (value == static_cast<double>(uint_value)) {
1646 *index = uint_value;
1647 return true;
1648 }
1649 }
1650 return false;
1651}
1652
1653
1654bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1655 if (!this->IsJSValue()) return false;
1656
1657 JSValue* js_value = JSValue::cast(this);
1658 if (!js_value->value()->IsString()) return false;
1659
1660 String* str = String::cast(js_value->value());
1661 if (index >= (uint32_t)str->length()) return false;
1662
1663 return true;
1664}
1665
1666
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001667FixedArrayBase* FixedArrayBase::cast(Object* object) {
1668 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1669 return reinterpret_cast<FixedArrayBase*>(object);
1670}
1671
1672
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001673Object* FixedArray::get(int index) {
1674 ASSERT(index >= 0 && index < this->length());
1675 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1676}
1677
1678
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001679void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001680 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001681 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001682 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1683 int offset = kHeaderSize + index * kPointerSize;
1684 WRITE_FIELD(this, offset, value);
1685}
1686
1687
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001688void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001689 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001690 ASSERT(index >= 0 && index < this->length());
1691 int offset = kHeaderSize + index * kPointerSize;
1692 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001693 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001694}
1695
1696
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001697inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1698 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1699}
1700
1701
1702inline double FixedDoubleArray::hole_nan_as_double() {
1703 return BitCast<double, uint64_t>(kHoleNanInt64);
1704}
1705
1706
1707inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1708 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1709 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1710 return OS::nan_value();
1711}
1712
1713
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001714double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001715 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1716 map() != HEAP->fixed_array_map());
1717 ASSERT(index >= 0 && index < this->length());
1718 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1719 ASSERT(!is_the_hole_nan(result));
1720 return result;
1721}
1722
danno@chromium.org88aa0582012-03-23 15:11:57 +00001723int64_t FixedDoubleArray::get_representation(int index) {
1724 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1725 map() != HEAP->fixed_array_map());
1726 ASSERT(index >= 0 && index < this->length());
1727 return READ_INT64_FIELD(this, kHeaderSize + index * kDoubleSize);
1728}
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001729
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001730MaybeObject* FixedDoubleArray::get(int index) {
1731 if (is_the_hole(index)) {
1732 return GetHeap()->the_hole_value();
1733 } else {
1734 return GetHeap()->NumberFromDouble(get_scalar(index));
1735 }
1736}
1737
1738
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001739void FixedDoubleArray::set(int index, double value) {
1740 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1741 map() != HEAP->fixed_array_map());
1742 int offset = kHeaderSize + index * kDoubleSize;
1743 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1744 WRITE_DOUBLE_FIELD(this, offset, value);
1745}
1746
1747
1748void FixedDoubleArray::set_the_hole(int index) {
1749 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1750 map() != HEAP->fixed_array_map());
1751 int offset = kHeaderSize + index * kDoubleSize;
1752 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1753}
1754
1755
1756bool FixedDoubleArray::is_the_hole(int index) {
1757 int offset = kHeaderSize + index * kDoubleSize;
1758 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1759}
1760
1761
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001762WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001763 Heap* heap = GetHeap();
1764 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1765 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001766 return UPDATE_WRITE_BARRIER;
1767}
1768
1769
1770void FixedArray::set(int index,
1771 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001772 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001773 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001774 ASSERT(index >= 0 && index < this->length());
1775 int offset = kHeaderSize + index * kPointerSize;
1776 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001777 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001778}
1779
1780
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001781void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1782 int index,
1783 Object* value) {
1784 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
1785 ASSERT(index >= 0 && index < array->length());
1786 int offset = kHeaderSize + index * kPointerSize;
1787 WRITE_FIELD(array, offset, value);
1788 Heap* heap = array->GetHeap();
1789 if (heap->InNewSpace(value)) {
1790 heap->RecordWrite(array->address(), offset);
1791 }
1792}
1793
1794
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001795void FixedArray::NoWriteBarrierSet(FixedArray* array,
1796 int index,
1797 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001798 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001799 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001800 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001801 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1802}
1803
1804
1805void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001806 ASSERT(map() != HEAP->fixed_cow_array_map());
1807 set_undefined(GetHeap(), index);
1808}
1809
1810
1811void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001812 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001813 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001814 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001815 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001816}
1817
1818
ager@chromium.org236ad962008-09-25 09:45:57 +00001819void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001820 set_null(GetHeap(), index);
1821}
1822
1823
1824void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001825 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001826 ASSERT(!heap->InNewSpace(heap->null_value()));
1827 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001828}
1829
1830
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001831void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001832 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001833 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001834 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1835 WRITE_FIELD(this,
1836 kHeaderSize + index * kPointerSize,
1837 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001838}
1839
1840
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001841void FixedArray::set_unchecked(int index, Smi* value) {
1842 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1843 int offset = kHeaderSize + index * kPointerSize;
1844 WRITE_FIELD(this, offset, value);
1845}
1846
1847
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001848void FixedArray::set_unchecked(Heap* heap,
1849 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001850 Object* value,
1851 WriteBarrierMode mode) {
1852 int offset = kHeaderSize + index * kPointerSize;
1853 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001854 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001855}
1856
1857
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001858void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001859 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001860 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1861 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001862}
1863
1864
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001865Object** FixedArray::data_start() {
1866 return HeapObject::RawField(this, kHeaderSize);
1867}
1868
1869
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001870bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001871 ASSERT(this->IsSmi() ||
1872 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001873 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001874 return this->IsSmi() || length() <= kFirstIndex;
1875}
1876
1877
1878int DescriptorArray::bit_field3_storage() {
1879 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1880 return Smi::cast(storage)->value();
1881}
1882
1883void DescriptorArray::set_bit_field3_storage(int value) {
1884 ASSERT(!IsEmpty());
1885 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001886}
1887
1888
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001889void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1890 int first,
1891 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001892 Object* tmp = array->get(first);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001893 NoIncrementalWriteBarrierSet(array, first, array->get(second));
1894 NoIncrementalWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001895}
1896
1897
1898int DescriptorArray::Search(String* name) {
1899 SLOW_ASSERT(IsSortedNoDuplicates());
1900
1901 // Check for empty descriptor array.
1902 int nof = number_of_descriptors();
1903 if (nof == 0) return kNotFound;
1904
1905 // Fast case: do linear search for small arrays.
1906 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001907 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001908 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001909 }
1910
1911 // Slow case: perform binary search.
1912 return BinarySearch(name, 0, nof - 1);
1913}
1914
1915
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001916int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001917 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001918 if (number == DescriptorLookupCache::kAbsent) {
1919 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001920 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001921 }
1922 return number;
1923}
1924
1925
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001926String* DescriptorArray::GetKey(int descriptor_number) {
1927 ASSERT(descriptor_number < number_of_descriptors());
1928 return String::cast(get(ToKeyIndex(descriptor_number)));
1929}
1930
1931
1932Object* DescriptorArray::GetValue(int descriptor_number) {
1933 ASSERT(descriptor_number < number_of_descriptors());
1934 return GetContentArray()->get(ToValueIndex(descriptor_number));
1935}
1936
1937
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001938PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001939 ASSERT(descriptor_number < number_of_descriptors());
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001940 Object* details = GetContentArray()->get(ToDetailsIndex(descriptor_number));
1941 return PropertyDetails(Smi::cast(details));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001942}
1943
1944
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001945PropertyType DescriptorArray::GetType(int descriptor_number) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001946 return GetDetails(descriptor_number).type();
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001947}
1948
1949
1950int DescriptorArray::GetFieldIndex(int descriptor_number) {
1951 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1952}
1953
1954
1955JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1956 return JSFunction::cast(GetValue(descriptor_number));
1957}
1958
1959
1960Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1961 ASSERT(GetType(descriptor_number) == CALLBACKS);
1962 return GetValue(descriptor_number);
1963}
1964
1965
1966AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1967 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001968 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001969 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001970}
1971
1972
1973bool DescriptorArray::IsProperty(int descriptor_number) {
ulan@chromium.org9a21ec42012-03-06 08:42:24 +00001974 Entry entry(this, descriptor_number);
1975 return IsPropertyDescriptor(&entry);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001976}
1977
1978
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001979bool DescriptorArray::IsTransitionOnly(int descriptor_number) {
1980 switch (GetType(descriptor_number)) {
1981 case MAP_TRANSITION:
1982 case CONSTANT_TRANSITION:
1983 case ELEMENTS_TRANSITION:
1984 return true;
1985 case CALLBACKS: {
1986 Object* value = GetValue(descriptor_number);
1987 if (!value->IsAccessorPair()) return false;
1988 AccessorPair* accessors = AccessorPair::cast(value);
1989 return accessors->getter()->IsMap() && accessors->setter()->IsMap();
1990 }
1991 case NORMAL:
1992 case FIELD:
1993 case CONSTANT_FUNCTION:
1994 case HANDLER:
1995 case INTERCEPTOR:
1996 case NULL_DESCRIPTOR:
1997 return false;
1998 }
1999 UNREACHABLE(); // Keep the compiler happy.
2000 return false;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002001}
2002
2003
2004bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
2005 return GetType(descriptor_number) == NULL_DESCRIPTOR;
2006}
2007
2008
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002009void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2010 desc->Init(GetKey(descriptor_number),
2011 GetValue(descriptor_number),
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002012 GetDetails(descriptor_number));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002013}
2014
2015
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002016void DescriptorArray::Set(int descriptor_number,
2017 Descriptor* desc,
2018 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002019 // Range check.
2020 ASSERT(descriptor_number < number_of_descriptors());
2021
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002022 NoIncrementalWriteBarrierSet(this,
2023 ToKeyIndex(descriptor_number),
2024 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002025 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002026 NoIncrementalWriteBarrierSet(content_array,
2027 ToValueIndex(descriptor_number),
2028 desc->GetValue());
2029 NoIncrementalWriteBarrierSet(content_array,
2030 ToDetailsIndex(descriptor_number),
2031 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002032}
2033
2034
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002035void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2036 int first, int second) {
2037 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002038 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002039 NoIncrementalWriteBarrierSwap(content_array,
2040 ToValueIndex(first),
2041 ToValueIndex(second));
2042 NoIncrementalWriteBarrierSwap(content_array,
2043 ToDetailsIndex(first),
2044 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002045}
2046
2047
2048DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
2049 : marking_(array->GetHeap()->incremental_marking()) {
2050 marking_->EnterNoMarkingScope();
2051 if (array->number_of_descriptors() > 0) {
2052 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
2053 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
2054 }
2055}
2056
2057
2058DescriptorArray::WhitenessWitness::~WhitenessWitness() {
2059 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002060}
2061
2062
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002063template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002064int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2065 const int kMinCapacity = 32;
2066 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2067 if (capacity < kMinCapacity) {
2068 capacity = kMinCapacity; // Guarantee min capacity.
2069 }
2070 return capacity;
2071}
2072
2073
2074template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002075int HashTable<Shape, Key>::FindEntry(Key key) {
2076 return FindEntry(GetIsolate(), key);
2077}
2078
2079
2080// Find entry for key otherwise return kNotFound.
2081template<typename Shape, typename Key>
2082int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2083 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002084 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002085 uint32_t count = 1;
2086 // EnsureCapacity will guarantee the hash table is never full.
2087 while (true) {
2088 Object* element = KeyAt(entry);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002089 // Empty entry.
2090 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2091 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002092 Shape::IsMatch(key, element)) return entry;
2093 entry = NextProbe(entry, count++, capacity);
2094 }
2095 return kNotFound;
2096}
2097
2098
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002099bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002100 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002101 if (!max_index_object->IsSmi()) return false;
2102 return 0 !=
2103 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2104}
2105
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002106uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002107 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002108 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002109 if (!max_index_object->IsSmi()) return 0;
2110 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2111 return value >> kRequiresSlowElementsTagSize;
2112}
2113
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002114void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002115 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002116}
2117
2118
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002119// ------------------------------------
2120// Cast operations
2121
2122
2123CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002124CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002125CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002126CAST_ACCESSOR(DeoptimizationInputData)
2127CAST_ACCESSOR(DeoptimizationOutputData)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002128CAST_ACCESSOR(TypeFeedbackCells)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002129CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002130CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002131CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002132CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002133CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002134CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002135CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002136CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002137CAST_ACCESSOR(String)
2138CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002139CAST_ACCESSOR(SeqAsciiString)
2140CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002141CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002142CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002143CAST_ACCESSOR(ExternalString)
2144CAST_ACCESSOR(ExternalAsciiString)
2145CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002146CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002147CAST_ACCESSOR(JSObject)
2148CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002149CAST_ACCESSOR(HeapObject)
2150CAST_ACCESSOR(HeapNumber)
2151CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002152CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002153CAST_ACCESSOR(SharedFunctionInfo)
2154CAST_ACCESSOR(Map)
2155CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002156CAST_ACCESSOR(GlobalObject)
2157CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002158CAST_ACCESSOR(JSGlobalObject)
2159CAST_ACCESSOR(JSBuiltinsObject)
2160CAST_ACCESSOR(Code)
2161CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002162CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002163CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002164CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002165CAST_ACCESSOR(JSSet)
2166CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002167CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002168CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002169CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002170CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002171CAST_ACCESSOR(ExternalArray)
2172CAST_ACCESSOR(ExternalByteArray)
2173CAST_ACCESSOR(ExternalUnsignedByteArray)
2174CAST_ACCESSOR(ExternalShortArray)
2175CAST_ACCESSOR(ExternalUnsignedShortArray)
2176CAST_ACCESSOR(ExternalIntArray)
2177CAST_ACCESSOR(ExternalUnsignedIntArray)
2178CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002179CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002180CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002181CAST_ACCESSOR(Struct)
2182
2183
2184#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2185 STRUCT_LIST(MAKE_STRUCT_CAST)
2186#undef MAKE_STRUCT_CAST
2187
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002188
2189template <typename Shape, typename Key>
2190HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002191 ASSERT(obj->IsHashTable());
2192 return reinterpret_cast<HashTable*>(obj);
2193}
2194
2195
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002196SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002197SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002198
ager@chromium.orgac091b72010-05-05 07:34:42 +00002199SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002200
2201
2202uint32_t String::hash_field() {
2203 return READ_UINT32_FIELD(this, kHashFieldOffset);
2204}
2205
2206
2207void String::set_hash_field(uint32_t value) {
2208 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002209#if V8_HOST_ARCH_64_BIT
2210 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2211#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002212}
2213
2214
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002215bool String::Equals(String* other) {
2216 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002217 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2218 return false;
2219 }
2220 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002221}
2222
2223
lrn@chromium.org303ada72010-10-27 09:33:13 +00002224MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002225 if (!StringShape(this).IsCons()) return this;
2226 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002227 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002228 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002229}
2230
2231
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002232String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002233 MaybeObject* flat = TryFlatten(pretenure);
2234 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002235 if (!flat->ToObject(&successfully_flattened)) return this;
2236 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002237}
2238
2239
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002240uint16_t String::Get(int index) {
2241 ASSERT(index >= 0 && index < length());
2242 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002243 case kSeqStringTag | kAsciiStringTag:
2244 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2245 case kSeqStringTag | kTwoByteStringTag:
2246 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2247 case kConsStringTag | kAsciiStringTag:
2248 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002249 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002250 case kExternalStringTag | kAsciiStringTag:
2251 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2252 case kExternalStringTag | kTwoByteStringTag:
2253 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002254 case kSlicedStringTag | kAsciiStringTag:
2255 case kSlicedStringTag | kTwoByteStringTag:
2256 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002257 default:
2258 break;
2259 }
2260
2261 UNREACHABLE();
2262 return 0;
2263}
2264
2265
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002266void String::Set(int index, uint16_t value) {
2267 ASSERT(index >= 0 && index < length());
2268 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002269
ager@chromium.org5ec48922009-05-05 07:25:34 +00002270 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002271 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2272 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002273}
2274
2275
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002276bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002277 if (!StringShape(this).IsCons()) return true;
2278 return ConsString::cast(this)->second()->length() == 0;
2279}
2280
2281
2282String* String::GetUnderlying() {
2283 // Giving direct access to underlying string only makes sense if the
2284 // wrapping string is already flattened.
2285 ASSERT(this->IsFlat());
2286 ASSERT(StringShape(this).IsIndirect());
2287 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2288 const int kUnderlyingOffset = SlicedString::kParentOffset;
2289 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002290}
2291
2292
ager@chromium.org7c537e22008-10-16 08:43:32 +00002293uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002294 ASSERT(index >= 0 && index < length());
2295 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2296}
2297
2298
ager@chromium.org7c537e22008-10-16 08:43:32 +00002299void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002300 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2301 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2302 static_cast<byte>(value));
2303}
2304
2305
ager@chromium.org7c537e22008-10-16 08:43:32 +00002306Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002307 return FIELD_ADDR(this, kHeaderSize);
2308}
2309
2310
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002311char* SeqAsciiString::GetChars() {
2312 return reinterpret_cast<char*>(GetCharsAddress());
2313}
2314
2315
ager@chromium.org7c537e22008-10-16 08:43:32 +00002316Address SeqTwoByteString::GetCharsAddress() {
2317 return FIELD_ADDR(this, kHeaderSize);
2318}
2319
2320
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002321uc16* SeqTwoByteString::GetChars() {
2322 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2323}
2324
2325
ager@chromium.org7c537e22008-10-16 08:43:32 +00002326uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002327 ASSERT(index >= 0 && index < length());
2328 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2329}
2330
2331
ager@chromium.org7c537e22008-10-16 08:43:32 +00002332void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002333 ASSERT(index >= 0 && index < length());
2334 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2335}
2336
2337
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002338int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002339 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002340}
2341
2342
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002343int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002344 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002345}
2346
2347
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002348String* SlicedString::parent() {
2349 return String::cast(READ_FIELD(this, kParentOffset));
2350}
2351
2352
2353void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002354 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002355 WRITE_FIELD(this, kParentOffset, parent);
2356}
2357
2358
2359SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2360
2361
ager@chromium.org870a0b62008-11-04 11:43:05 +00002362String* ConsString::first() {
2363 return String::cast(READ_FIELD(this, kFirstOffset));
2364}
2365
2366
2367Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002368 return READ_FIELD(this, kFirstOffset);
2369}
2370
2371
ager@chromium.org870a0b62008-11-04 11:43:05 +00002372void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002373 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002374 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002375}
2376
2377
ager@chromium.org870a0b62008-11-04 11:43:05 +00002378String* ConsString::second() {
2379 return String::cast(READ_FIELD(this, kSecondOffset));
2380}
2381
2382
2383Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002384 return READ_FIELD(this, kSecondOffset);
2385}
2386
2387
ager@chromium.org870a0b62008-11-04 11:43:05 +00002388void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002389 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002390 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002391}
2392
2393
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002394bool ExternalString::is_short() {
2395 InstanceType type = map()->instance_type();
2396 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002397}
2398
2399
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002400const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002401 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2402}
2403
2404
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002405void ExternalAsciiString::update_data_cache() {
2406 if (is_short()) return;
2407 const char** data_field =
2408 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2409 *data_field = resource()->data();
2410}
2411
2412
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002413void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002414 const ExternalAsciiString::Resource* resource) {
2415 *reinterpret_cast<const Resource**>(
2416 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002417 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002418}
2419
2420
2421const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002422 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002423}
2424
2425
2426uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2427 ASSERT(index >= 0 && index < length());
2428 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002429}
2430
2431
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002432const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002433 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2434}
2435
2436
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002437void ExternalTwoByteString::update_data_cache() {
2438 if (is_short()) return;
2439 const uint16_t** data_field =
2440 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2441 *data_field = resource()->data();
2442}
2443
2444
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002445void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002446 const ExternalTwoByteString::Resource* resource) {
2447 *reinterpret_cast<const Resource**>(
2448 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002449 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002450}
2451
2452
2453const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002454 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002455}
2456
2457
2458uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2459 ASSERT(index >= 0 && index < length());
2460 return GetChars()[index];
2461}
2462
2463
2464const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2465 unsigned start) {
2466 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002467}
2468
2469
ager@chromium.orgac091b72010-05-05 07:34:42 +00002470void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002471 set_finger_index(kEntriesIndex);
2472 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002473}
2474
2475
2476void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002477 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002478 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002479 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002480 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002481 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002482 MakeZeroSize();
2483}
2484
2485
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002486int JSFunctionResultCache::size() {
2487 return Smi::cast(get(kCacheSizeIndex))->value();
2488}
2489
2490
2491void JSFunctionResultCache::set_size(int size) {
2492 set(kCacheSizeIndex, Smi::FromInt(size));
2493}
2494
2495
2496int JSFunctionResultCache::finger_index() {
2497 return Smi::cast(get(kFingerIndex))->value();
2498}
2499
2500
2501void JSFunctionResultCache::set_finger_index(int finger_index) {
2502 set(kFingerIndex, Smi::FromInt(finger_index));
2503}
2504
2505
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002506byte ByteArray::get(int index) {
2507 ASSERT(index >= 0 && index < this->length());
2508 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2509}
2510
2511
2512void ByteArray::set(int index, byte value) {
2513 ASSERT(index >= 0 && index < this->length());
2514 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2515}
2516
2517
2518int ByteArray::get_int(int index) {
2519 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2520 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2521}
2522
2523
2524ByteArray* ByteArray::FromDataStartAddress(Address address) {
2525 ASSERT_TAG_ALIGNED(address);
2526 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2527}
2528
2529
2530Address ByteArray::GetDataStartAddress() {
2531 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2532}
2533
2534
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002535uint8_t* ExternalPixelArray::external_pixel_pointer() {
2536 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002537}
2538
2539
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002540uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002541 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002542 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002543 return ptr[index];
2544}
2545
2546
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002547MaybeObject* ExternalPixelArray::get(int index) {
2548 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2549}
2550
2551
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002552void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002553 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002554 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002555 ptr[index] = value;
2556}
2557
2558
ager@chromium.org3811b432009-10-28 14:53:37 +00002559void* ExternalArray::external_pointer() {
2560 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2561 return reinterpret_cast<void*>(ptr);
2562}
2563
2564
2565void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2566 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2567 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2568}
2569
2570
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002571int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002572 ASSERT((index >= 0) && (index < this->length()));
2573 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2574 return ptr[index];
2575}
2576
2577
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002578MaybeObject* ExternalByteArray::get(int index) {
2579 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2580}
2581
2582
ager@chromium.org3811b432009-10-28 14:53:37 +00002583void ExternalByteArray::set(int index, int8_t value) {
2584 ASSERT((index >= 0) && (index < this->length()));
2585 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2586 ptr[index] = value;
2587}
2588
2589
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002590uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002591 ASSERT((index >= 0) && (index < this->length()));
2592 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2593 return ptr[index];
2594}
2595
2596
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002597MaybeObject* ExternalUnsignedByteArray::get(int index) {
2598 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2599}
2600
2601
ager@chromium.org3811b432009-10-28 14:53:37 +00002602void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2603 ASSERT((index >= 0) && (index < this->length()));
2604 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2605 ptr[index] = value;
2606}
2607
2608
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002609int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002610 ASSERT((index >= 0) && (index < this->length()));
2611 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2612 return ptr[index];
2613}
2614
2615
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002616MaybeObject* ExternalShortArray::get(int index) {
2617 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2618}
2619
2620
ager@chromium.org3811b432009-10-28 14:53:37 +00002621void ExternalShortArray::set(int index, int16_t value) {
2622 ASSERT((index >= 0) && (index < this->length()));
2623 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2624 ptr[index] = value;
2625}
2626
2627
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002628uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002629 ASSERT((index >= 0) && (index < this->length()));
2630 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2631 return ptr[index];
2632}
2633
2634
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002635MaybeObject* ExternalUnsignedShortArray::get(int index) {
2636 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2637}
2638
2639
ager@chromium.org3811b432009-10-28 14:53:37 +00002640void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2641 ASSERT((index >= 0) && (index < this->length()));
2642 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2643 ptr[index] = value;
2644}
2645
2646
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002647int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002648 ASSERT((index >= 0) && (index < this->length()));
2649 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2650 return ptr[index];
2651}
2652
2653
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002654MaybeObject* ExternalIntArray::get(int index) {
2655 return GetHeap()->NumberFromInt32(get_scalar(index));
2656}
2657
2658
ager@chromium.org3811b432009-10-28 14:53:37 +00002659void ExternalIntArray::set(int index, int32_t value) {
2660 ASSERT((index >= 0) && (index < this->length()));
2661 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2662 ptr[index] = value;
2663}
2664
2665
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002666uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002667 ASSERT((index >= 0) && (index < this->length()));
2668 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2669 return ptr[index];
2670}
2671
2672
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002673MaybeObject* ExternalUnsignedIntArray::get(int index) {
2674 return GetHeap()->NumberFromUint32(get_scalar(index));
2675}
2676
2677
ager@chromium.org3811b432009-10-28 14:53:37 +00002678void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2679 ASSERT((index >= 0) && (index < this->length()));
2680 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2681 ptr[index] = value;
2682}
2683
2684
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002685float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002686 ASSERT((index >= 0) && (index < this->length()));
2687 float* ptr = static_cast<float*>(external_pointer());
2688 return ptr[index];
2689}
2690
2691
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002692MaybeObject* ExternalFloatArray::get(int index) {
2693 return GetHeap()->NumberFromDouble(get_scalar(index));
2694}
2695
2696
ager@chromium.org3811b432009-10-28 14:53:37 +00002697void ExternalFloatArray::set(int index, float value) {
2698 ASSERT((index >= 0) && (index < this->length()));
2699 float* ptr = static_cast<float*>(external_pointer());
2700 ptr[index] = value;
2701}
2702
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002703
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002704double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002705 ASSERT((index >= 0) && (index < this->length()));
2706 double* ptr = static_cast<double*>(external_pointer());
2707 return ptr[index];
2708}
2709
2710
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002711MaybeObject* ExternalDoubleArray::get(int index) {
2712 return GetHeap()->NumberFromDouble(get_scalar(index));
2713}
2714
2715
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002716void ExternalDoubleArray::set(int index, double value) {
2717 ASSERT((index >= 0) && (index < this->length()));
2718 double* ptr = static_cast<double*>(external_pointer());
2719 ptr[index] = value;
2720}
2721
2722
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002723int Map::visitor_id() {
2724 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2725}
2726
2727
2728void Map::set_visitor_id(int id) {
2729 ASSERT(0 <= id && id < 256);
2730 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2731}
2732
ager@chromium.org3811b432009-10-28 14:53:37 +00002733
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002734int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002735 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2736}
2737
2738
2739int Map::inobject_properties() {
2740 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002741}
2742
2743
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002744int Map::pre_allocated_property_fields() {
2745 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2746}
2747
2748
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002749int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002750 int instance_size = map->instance_size();
2751 if (instance_size != kVariableSizeSentinel) return instance_size;
2752 // We can ignore the "symbol" bit becase it is only set for symbols
2753 // and implies a string type.
2754 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002755 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002756 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002757 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002758 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002759 if (instance_type == ASCII_STRING_TYPE) {
2760 return SeqAsciiString::SizeFor(
2761 reinterpret_cast<SeqAsciiString*>(this)->length());
2762 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002763 if (instance_type == BYTE_ARRAY_TYPE) {
2764 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2765 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002766 if (instance_type == FREE_SPACE_TYPE) {
2767 return reinterpret_cast<FreeSpace*>(this)->size();
2768 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002769 if (instance_type == STRING_TYPE) {
2770 return SeqTwoByteString::SizeFor(
2771 reinterpret_cast<SeqTwoByteString*>(this)->length());
2772 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002773 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2774 return FixedDoubleArray::SizeFor(
2775 reinterpret_cast<FixedDoubleArray*>(this)->length());
2776 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002777 ASSERT(instance_type == CODE_TYPE);
2778 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002779}
2780
2781
2782void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002783 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002784 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002785 ASSERT(0 <= value && value < 256);
2786 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2787}
2788
2789
ager@chromium.org7c537e22008-10-16 08:43:32 +00002790void Map::set_inobject_properties(int value) {
2791 ASSERT(0 <= value && value < 256);
2792 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2793}
2794
2795
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002796void Map::set_pre_allocated_property_fields(int value) {
2797 ASSERT(0 <= value && value < 256);
2798 WRITE_BYTE_FIELD(this,
2799 kPreAllocatedPropertyFieldsOffset,
2800 static_cast<byte>(value));
2801}
2802
2803
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002804InstanceType Map::instance_type() {
2805 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2806}
2807
2808
2809void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002810 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2811}
2812
2813
2814int Map::unused_property_fields() {
2815 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2816}
2817
2818
2819void Map::set_unused_property_fields(int value) {
2820 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2821}
2822
2823
2824byte Map::bit_field() {
2825 return READ_BYTE_FIELD(this, kBitFieldOffset);
2826}
2827
2828
2829void Map::set_bit_field(byte value) {
2830 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2831}
2832
2833
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002834byte Map::bit_field2() {
2835 return READ_BYTE_FIELD(this, kBitField2Offset);
2836}
2837
2838
2839void Map::set_bit_field2(byte value) {
2840 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2841}
2842
2843
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002844void Map::set_non_instance_prototype(bool value) {
2845 if (value) {
2846 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2847 } else {
2848 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2849 }
2850}
2851
2852
2853bool Map::has_non_instance_prototype() {
2854 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2855}
2856
2857
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002858void Map::set_function_with_prototype(bool value) {
2859 if (value) {
2860 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2861 } else {
2862 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2863 }
2864}
2865
2866
2867bool Map::function_with_prototype() {
2868 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2869}
2870
2871
ager@chromium.org870a0b62008-11-04 11:43:05 +00002872void Map::set_is_access_check_needed(bool access_check_needed) {
2873 if (access_check_needed) {
2874 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2875 } else {
2876 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2877 }
2878}
2879
2880
2881bool Map::is_access_check_needed() {
2882 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2883}
2884
2885
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002886void Map::set_is_extensible(bool value) {
2887 if (value) {
2888 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2889 } else {
2890 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2891 }
2892}
2893
2894bool Map::is_extensible() {
2895 return ((1 << kIsExtensible) & bit_field2()) != 0;
2896}
2897
2898
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002899void Map::set_attached_to_shared_function_info(bool value) {
2900 if (value) {
2901 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2902 } else {
2903 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2904 }
2905}
2906
2907bool Map::attached_to_shared_function_info() {
2908 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2909}
2910
2911
2912void Map::set_is_shared(bool value) {
2913 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002914 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002915 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002916 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002917 }
2918}
2919
2920bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002921 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002922}
2923
2924
2925JSFunction* Map::unchecked_constructor() {
2926 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2927}
2928
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002929
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002930Code::Flags Code::flags() {
2931 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2932}
2933
2934
2935void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002936 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002937 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002938 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2939 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002940 ExtractArgumentsCountFromFlags(flags) >= 0);
2941 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2942}
2943
2944
2945Code::Kind Code::kind() {
2946 return ExtractKindFromFlags(flags());
2947}
2948
2949
kasper.lund7276f142008-07-30 08:49:36 +00002950InlineCacheState Code::ic_state() {
2951 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002952 // Only allow uninitialized or debugger states for non-IC code
2953 // objects. This is used in the debugger to determine whether or not
2954 // a call to code object has been replaced with a debug break call.
2955 ASSERT(is_inline_cache_stub() ||
2956 result == UNINITIALIZED ||
2957 result == DEBUG_BREAK ||
2958 result == DEBUG_PREPARE_STEP_IN);
2959 return result;
2960}
2961
2962
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002963Code::ExtraICState Code::extra_ic_state() {
2964 ASSERT(is_inline_cache_stub());
2965 return ExtractExtraICStateFromFlags(flags());
2966}
2967
2968
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002969PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002970 return ExtractTypeFromFlags(flags());
2971}
2972
2973
2974int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002975 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002976 return ExtractArgumentsCountFromFlags(flags());
2977}
2978
2979
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002980int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002981 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002982 kind() == UNARY_OP_IC ||
2983 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002984 kind() == COMPARE_IC ||
2985 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002986 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002987}
2988
2989
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002990void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002991 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002992 kind() == UNARY_OP_IC ||
2993 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002994 kind() == COMPARE_IC ||
2995 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002996 ASSERT(0 <= major && major < 256);
2997 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002998}
2999
3000
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003001bool Code::is_pregenerated() {
3002 return kind() == STUB && IsPregeneratedField::decode(flags());
3003}
3004
3005
3006void Code::set_is_pregenerated(bool value) {
3007 ASSERT(kind() == STUB);
3008 Flags f = flags();
3009 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3010 set_flags(f);
3011}
3012
3013
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003014bool Code::optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003015 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003016 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3017}
3018
3019
3020void Code::set_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003021 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003022 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3023}
3024
3025
3026bool Code::has_deoptimization_support() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003027 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003028 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3029 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003030}
3031
3032
3033void Code::set_has_deoptimization_support(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003034 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003035 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3036 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3037 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3038}
3039
3040
3041bool Code::has_debug_break_slots() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003042 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003043 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3044 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3045}
3046
3047
3048void Code::set_has_debug_break_slots(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003049 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003050 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3051 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3052 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003053}
3054
3055
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003056bool Code::is_compiled_optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003057 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003058 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3059 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3060}
3061
3062
3063void Code::set_compiled_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003064 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003065 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3066 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3067 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3068}
3069
3070
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003071int Code::allow_osr_at_loop_nesting_level() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003072 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003073 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3074}
3075
3076
3077void Code::set_allow_osr_at_loop_nesting_level(int level) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003078 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003079 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3080 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3081}
3082
3083
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003084int Code::profiler_ticks() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003085 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003086 return READ_BYTE_FIELD(this, kProfilerTicksOffset);
3087}
3088
3089
3090void Code::set_profiler_ticks(int ticks) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003091 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003092 ASSERT(ticks < 256);
3093 WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
3094}
3095
3096
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003097unsigned Code::stack_slots() {
3098 ASSERT(kind() == OPTIMIZED_FUNCTION);
3099 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3100}
3101
3102
3103void Code::set_stack_slots(unsigned slots) {
3104 ASSERT(kind() == OPTIMIZED_FUNCTION);
3105 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3106}
3107
3108
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003109unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003110 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003111 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003112}
3113
3114
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003115void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003116 ASSERT(kind() == OPTIMIZED_FUNCTION);
3117 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003118 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003119}
3120
3121
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003122unsigned Code::stack_check_table_offset() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003123 ASSERT_EQ(FUNCTION, kind());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003124 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003125}
3126
3127
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003128void Code::set_stack_check_table_offset(unsigned offset) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003129 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003130 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003131 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003132}
3133
3134
3135CheckType Code::check_type() {
3136 ASSERT(is_call_stub() || is_keyed_call_stub());
3137 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3138 return static_cast<CheckType>(type);
3139}
3140
3141
3142void Code::set_check_type(CheckType value) {
3143 ASSERT(is_call_stub() || is_keyed_call_stub());
3144 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3145}
3146
3147
danno@chromium.org40cb8782011-05-25 07:58:50 +00003148byte Code::unary_op_type() {
3149 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003150 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3151}
3152
3153
danno@chromium.org40cb8782011-05-25 07:58:50 +00003154void Code::set_unary_op_type(byte value) {
3155 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003156 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3157}
3158
3159
danno@chromium.org40cb8782011-05-25 07:58:50 +00003160byte Code::binary_op_type() {
3161 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003162 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3163}
3164
3165
danno@chromium.org40cb8782011-05-25 07:58:50 +00003166void Code::set_binary_op_type(byte value) {
3167 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003168 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3169}
3170
3171
danno@chromium.org40cb8782011-05-25 07:58:50 +00003172byte Code::binary_op_result_type() {
3173 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003174 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3175}
3176
3177
danno@chromium.org40cb8782011-05-25 07:58:50 +00003178void Code::set_binary_op_result_type(byte value) {
3179 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003180 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3181}
3182
3183
3184byte Code::compare_state() {
3185 ASSERT(is_compare_ic_stub());
3186 return READ_BYTE_FIELD(this, kCompareStateOffset);
3187}
3188
3189
3190void Code::set_compare_state(byte value) {
3191 ASSERT(is_compare_ic_stub());
3192 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3193}
3194
3195
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003196byte Code::compare_operation() {
3197 ASSERT(is_compare_ic_stub());
3198 return READ_BYTE_FIELD(this, kCompareOperationOffset);
3199}
3200
3201
3202void Code::set_compare_operation(byte value) {
3203 ASSERT(is_compare_ic_stub());
3204 WRITE_BYTE_FIELD(this, kCompareOperationOffset, value);
3205}
3206
3207
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003208byte Code::to_boolean_state() {
3209 ASSERT(is_to_boolean_ic_stub());
3210 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3211}
3212
3213
3214void Code::set_to_boolean_state(byte value) {
3215 ASSERT(is_to_boolean_ic_stub());
3216 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3217}
3218
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003219
3220bool Code::has_function_cache() {
3221 ASSERT(kind() == STUB);
3222 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3223}
3224
3225
3226void Code::set_has_function_cache(bool flag) {
3227 ASSERT(kind() == STUB);
3228 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3229}
3230
3231
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003232bool Code::is_inline_cache_stub() {
3233 Kind kind = this->kind();
3234 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3235}
3236
3237
3238Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003239 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003240 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003241 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003242 int argc,
3243 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003244 // Extra IC state is only allowed for call IC stubs or for store IC
3245 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003246 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003247 kind == CALL_IC ||
3248 kind == STORE_IC ||
3249 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003250 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003251 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003252 | ICStateField::encode(ic_state)
3253 | TypeField::encode(type)
3254 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003255 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003256 | CacheHolderField::encode(holder);
3257 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003258}
3259
3260
3261Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3262 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003263 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003264 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003265 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003266 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003267}
3268
3269
3270Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003271 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003272}
3273
3274
kasper.lund7276f142008-07-30 08:49:36 +00003275InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003276 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003277}
3278
3279
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003280Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003281 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003282}
3283
3284
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003285PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003286 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003287}
3288
3289
3290int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003291 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003292}
3293
3294
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003295InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003296 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003297}
3298
3299
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003300Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003301 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003302 return static_cast<Flags>(bits);
3303}
3304
3305
ager@chromium.org8bb60582008-12-11 12:02:20 +00003306Code* Code::GetCodeFromTargetAddress(Address address) {
3307 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3308 // GetCodeFromTargetAddress might be called when marking objects during mark
3309 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3310 // Code::cast. Code::cast does not work when the object's map is
3311 // marked.
3312 Code* result = reinterpret_cast<Code*>(code);
3313 return result;
3314}
3315
3316
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003317Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3318 return HeapObject::
3319 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3320}
3321
3322
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003323Object* Map::prototype() {
3324 return READ_FIELD(this, kPrototypeOffset);
3325}
3326
3327
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003328void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003329 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003330 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003331 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003332}
3333
3334
danno@chromium.org40cb8782011-05-25 07:58:50 +00003335DescriptorArray* Map::instance_descriptors() {
3336 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3337 if (object->IsSmi()) {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003338 return GetHeap()->empty_descriptor_array();
danno@chromium.org40cb8782011-05-25 07:58:50 +00003339 } else {
3340 return DescriptorArray::cast(object);
3341 }
3342}
3343
3344
3345void Map::init_instance_descriptors() {
3346 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3347}
3348
3349
3350void Map::clear_instance_descriptors() {
3351 Object* object = READ_FIELD(this,
3352 kInstanceDescriptorsOrBitField3Offset);
3353 if (!object->IsSmi()) {
3354 WRITE_FIELD(
3355 this,
3356 kInstanceDescriptorsOrBitField3Offset,
3357 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3358 }
3359}
3360
3361
3362void Map::set_instance_descriptors(DescriptorArray* value,
3363 WriteBarrierMode mode) {
3364 Object* object = READ_FIELD(this,
3365 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003366 Heap* heap = GetHeap();
3367 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003368 clear_instance_descriptors();
3369 return;
3370 } else {
3371 if (object->IsSmi()) {
3372 value->set_bit_field3_storage(Smi::cast(object)->value());
3373 } else {
3374 value->set_bit_field3_storage(
3375 DescriptorArray::cast(object)->bit_field3_storage());
3376 }
3377 }
3378 ASSERT(!is_shared());
3379 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003380 CONDITIONAL_WRITE_BARRIER(
3381 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003382}
3383
3384
3385int Map::bit_field3() {
3386 Object* object = READ_FIELD(this,
3387 kInstanceDescriptorsOrBitField3Offset);
3388 if (object->IsSmi()) {
3389 return Smi::cast(object)->value();
3390 } else {
3391 return DescriptorArray::cast(object)->bit_field3_storage();
3392 }
3393}
3394
3395
3396void Map::set_bit_field3(int value) {
3397 ASSERT(Smi::IsValid(value));
3398 Object* object = READ_FIELD(this,
3399 kInstanceDescriptorsOrBitField3Offset);
3400 if (object->IsSmi()) {
3401 WRITE_FIELD(this,
3402 kInstanceDescriptorsOrBitField3Offset,
3403 Smi::FromInt(value));
3404 } else {
3405 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3406 }
3407}
3408
3409
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003410Object* Map::GetBackPointer() {
3411 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3412 if (object->IsFixedArray()) {
3413 return FixedArray::cast(object)->get(kProtoTransitionBackPointerOffset);
3414 } else {
3415 return object;
3416 }
3417}
3418
3419
3420void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
3421 Heap* heap = GetHeap();
3422 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
3423 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
3424 (value->IsMap() && GetBackPointer()->IsUndefined()));
3425 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3426 if (object->IsFixedArray()) {
3427 FixedArray::cast(object)->set(
3428 kProtoTransitionBackPointerOffset, value, mode);
3429 } else {
3430 WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
3431 CONDITIONAL_WRITE_BARRIER(
3432 heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
3433 }
3434}
3435
3436
3437FixedArray* Map::prototype_transitions() {
3438 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3439 if (object->IsFixedArray()) {
3440 return FixedArray::cast(object);
3441 } else {
3442 return GetHeap()->empty_fixed_array();
3443 }
3444}
3445
3446
3447void Map::set_prototype_transitions(FixedArray* value, WriteBarrierMode mode) {
3448 Heap* heap = GetHeap();
3449 ASSERT(value != heap->empty_fixed_array());
3450 value->set(kProtoTransitionBackPointerOffset, GetBackPointer());
3451 WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
3452 CONDITIONAL_WRITE_BARRIER(
3453 heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
3454}
3455
3456
3457void Map::init_prototype_transitions(Object* undefined) {
3458 ASSERT(undefined->IsUndefined());
3459 WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, undefined);
3460}
3461
3462
3463HeapObject* Map::unchecked_prototype_transitions() {
3464 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3465 return reinterpret_cast<HeapObject*>(object);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003466}
3467
3468
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003469ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003470ACCESSORS(Map, constructor, Object, kConstructorOffset)
3471
3472ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003473ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003474ACCESSORS(JSFunction,
3475 next_function_link,
3476 Object,
3477 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003478
3479ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3480ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003481ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003482
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003483ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003484
3485ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3486ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3487ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3488ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003489ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003490
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003491ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3492ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3493
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003494ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3495ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3496ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3497
3498ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3499ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3500ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3501ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3502ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3503ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3504
3505ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3506ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3507
3508ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3509ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3510
3511ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3512ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003513ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3514 kPropertyAccessorsOffset)
3515ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3516 kPrototypeTemplateOffset)
3517ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3518ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3519 kNamedPropertyHandlerOffset)
3520ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3521 kIndexedPropertyHandlerOffset)
3522ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3523 kInstanceTemplateOffset)
3524ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3525ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003526ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3527 kInstanceCallHandlerOffset)
3528ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3529 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003530ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003531
3532ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003533ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3534 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003535
3536ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3537ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3538
3539ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3540
3541ACCESSORS(Script, source, Object, kSourceOffset)
3542ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003543ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003544ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
3545ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003546ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003547ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003548ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003549ACCESSORS_TO_SMI(Script, type, kTypeOffset)
3550ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
3551ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003552ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003553ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003554ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
3555 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003556
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003557#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003558ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3559ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3560ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3561ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3562
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003563ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
3564ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
3565ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003566ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003567#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003568
3569ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003570ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3571ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003572ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3573 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003574ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003575ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3576ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003577ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003578ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3579 kThisPropertyAssignmentsOffset)
danno@chromium.org1044a4d2012-04-30 12:34:39 +00003580SMI_ACCESSORS(SharedFunctionInfo, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003581
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00003582
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003583BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3584 kHiddenPrototypeBit)
3585BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3586BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3587 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003588BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3589 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003590BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3591 kIsExpressionBit)
3592BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3593 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003594BOOL_GETTER(SharedFunctionInfo,
3595 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003596 has_only_simple_this_property_assignments,
3597 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003598BOOL_ACCESSORS(SharedFunctionInfo,
3599 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003600 allows_lazy_compilation,
3601 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003602BOOL_ACCESSORS(SharedFunctionInfo,
3603 compiler_hints,
3604 uses_arguments,
3605 kUsesArguments)
3606BOOL_ACCESSORS(SharedFunctionInfo,
3607 compiler_hints,
3608 has_duplicate_parameters,
3609 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003610
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003611
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003612#if V8_HOST_ARCH_32_BIT
3613SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3614SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003615 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003616SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003617 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003618SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3619SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003620 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003621SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3622SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003623 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003624SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003625 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003626SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003627 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003628SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003629SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3630SMI_ACCESSORS(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003631#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003632
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003633#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003634 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003635 int holder::name() { \
3636 int value = READ_INT_FIELD(this, offset); \
3637 ASSERT(kHeapObjectTag == 1); \
3638 ASSERT((value & kHeapObjectTag) == 0); \
3639 return value >> 1; \
3640 } \
3641 void holder::set_##name(int value) { \
3642 ASSERT(kHeapObjectTag == 1); \
3643 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3644 (value & 0xC0000000) == 0x000000000); \
3645 WRITE_INT_FIELD(this, \
3646 offset, \
3647 (value << 1) & ~kHeapObjectTag); \
3648 }
3649
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003650#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3651 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003652 INT_ACCESSORS(holder, name, offset)
3653
3654
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003655PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003656PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3657 formal_parameter_count,
3658 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003659
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003660PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3661 expected_nof_properties,
3662 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003663PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3664
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003665PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3666PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3667 start_position_and_type,
3668 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003669
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003670PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3671 function_token_position,
3672 kFunctionTokenPositionOffset)
3673PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3674 compiler_hints,
3675 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003676
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003677PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3678 this_property_assignments_count,
3679 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003680PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003681
3682PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3683PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003684#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003685
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003686
3687int SharedFunctionInfo::construction_count() {
3688 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3689}
3690
3691
3692void SharedFunctionInfo::set_construction_count(int value) {
3693 ASSERT(0 <= value && value < 256);
3694 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3695}
3696
3697
whesse@chromium.org7b260152011-06-20 15:33:18 +00003698BOOL_ACCESSORS(SharedFunctionInfo,
3699 compiler_hints,
3700 live_objects_may_exist,
3701 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003702
3703
3704bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003705 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003706}
3707
3708
whesse@chromium.org7b260152011-06-20 15:33:18 +00003709BOOL_GETTER(SharedFunctionInfo,
3710 compiler_hints,
3711 optimization_disabled,
3712 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003713
3714
3715void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3716 set_compiler_hints(BooleanBit::set(compiler_hints(),
3717 kOptimizationDisabled,
3718 disable));
3719 // If disabling optimizations we reflect that in the code object so
3720 // it will not be counted as optimizable code.
3721 if ((code()->kind() == Code::FUNCTION) && disable) {
3722 code()->set_optimizable(false);
3723 }
3724}
3725
3726
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003727int SharedFunctionInfo::profiler_ticks() {
3728 if (code()->kind() != Code::FUNCTION) return 0;
3729 return code()->profiler_ticks();
3730}
3731
3732
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003733LanguageMode SharedFunctionInfo::language_mode() {
3734 int hints = compiler_hints();
3735 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3736 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3737 return EXTENDED_MODE;
3738 }
3739 return BooleanBit::get(hints, kStrictModeFunction)
3740 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003741}
3742
3743
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003744void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3745 // We only allow language mode transitions that go set the same language mode
3746 // again or go up in the chain:
3747 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3748 ASSERT(this->language_mode() == CLASSIC_MODE ||
3749 this->language_mode() == language_mode ||
3750 language_mode == EXTENDED_MODE);
3751 int hints = compiler_hints();
3752 hints = BooleanBit::set(
3753 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3754 hints = BooleanBit::set(
3755 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3756 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003757}
3758
3759
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003760bool SharedFunctionInfo::is_classic_mode() {
3761 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3762}
3763
3764BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3765 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003766BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3767BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3768 name_should_print_as_anonymous,
3769 kNameShouldPrintAsAnonymous)
3770BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3771BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00003772BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
3773BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
3774 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003775BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003776
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003777ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3778ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3779
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003780ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3781
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003782bool Script::HasValidSource() {
3783 Object* src = this->source();
3784 if (!src->IsString()) return true;
3785 String* src_str = String::cast(src);
3786 if (!StringShape(src_str).IsExternal()) return true;
3787 if (src_str->IsAsciiRepresentation()) {
3788 return ExternalAsciiString::cast(src)->resource() != NULL;
3789 } else if (src_str->IsTwoByteRepresentation()) {
3790 return ExternalTwoByteString::cast(src)->resource() != NULL;
3791 }
3792 return true;
3793}
3794
3795
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003796void SharedFunctionInfo::DontAdaptArguments() {
3797 ASSERT(code()->kind() == Code::BUILTIN);
3798 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3799}
3800
3801
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003802int SharedFunctionInfo::start_position() {
3803 return start_position_and_type() >> kStartPositionShift;
3804}
3805
3806
3807void SharedFunctionInfo::set_start_position(int start_position) {
3808 set_start_position_and_type((start_position << kStartPositionShift)
3809 | (start_position_and_type() & ~kStartPositionMask));
3810}
3811
3812
3813Code* SharedFunctionInfo::code() {
3814 return Code::cast(READ_FIELD(this, kCodeOffset));
3815}
3816
3817
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003818Code* SharedFunctionInfo::unchecked_code() {
3819 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3820}
3821
3822
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003823void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003824 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003825 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003826}
3827
3828
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003829ScopeInfo* SharedFunctionInfo::scope_info() {
3830 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003831}
3832
3833
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003834void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003835 WriteBarrierMode mode) {
3836 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003837 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3838 this,
3839 kScopeInfoOffset,
3840 reinterpret_cast<Object*>(value),
3841 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003842}
3843
3844
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003845bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003846 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003847 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003848}
3849
3850
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003851bool SharedFunctionInfo::IsApiFunction() {
3852 return function_data()->IsFunctionTemplateInfo();
3853}
3854
3855
3856FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3857 ASSERT(IsApiFunction());
3858 return FunctionTemplateInfo::cast(function_data());
3859}
3860
3861
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003862bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003863 return function_data()->IsSmi();
3864}
3865
3866
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003867BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3868 ASSERT(HasBuiltinFunctionId());
3869 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003870}
3871
3872
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003873int SharedFunctionInfo::code_age() {
3874 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3875}
3876
3877
3878void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00003879 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3880 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003881}
3882
3883
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003884bool SharedFunctionInfo::has_deoptimization_support() {
3885 Code* code = this->code();
3886 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3887}
3888
3889
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003890bool JSFunction::IsBuiltin() {
3891 return context()->global()->IsJSBuiltinsObject();
3892}
3893
3894
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003895bool JSFunction::NeedsArgumentsAdaption() {
3896 return shared()->formal_parameter_count() !=
3897 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3898}
3899
3900
3901bool JSFunction::IsOptimized() {
3902 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3903}
3904
3905
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003906bool JSFunction::IsOptimizable() {
3907 return code()->kind() == Code::FUNCTION && code()->optimizable();
3908}
3909
3910
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003911bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003912 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003913}
3914
3915
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003916Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003917 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003918}
3919
3920
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003921Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003922 return reinterpret_cast<Code*>(
3923 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003924}
3925
3926
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003927void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003928 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003929 Address entry = value->entry();
3930 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003931 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3932 this,
3933 HeapObject::RawField(this, kCodeEntryOffset),
3934 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003935}
3936
3937
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003938void JSFunction::ReplaceCode(Code* code) {
3939 bool was_optimized = IsOptimized();
3940 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3941
3942 set_code(code);
3943
3944 // Add/remove the function from the list of optimized functions for this
3945 // context based on the state change.
3946 if (!was_optimized && is_optimized) {
3947 context()->global_context()->AddOptimizedFunction(this);
3948 }
3949 if (was_optimized && !is_optimized) {
3950 context()->global_context()->RemoveOptimizedFunction(this);
3951 }
3952}
3953
3954
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003955Context* JSFunction::context() {
3956 return Context::cast(READ_FIELD(this, kContextOffset));
3957}
3958
3959
3960Object* JSFunction::unchecked_context() {
3961 return READ_FIELD(this, kContextOffset);
3962}
3963
3964
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003965SharedFunctionInfo* JSFunction::unchecked_shared() {
3966 return reinterpret_cast<SharedFunctionInfo*>(
3967 READ_FIELD(this, kSharedFunctionInfoOffset));
3968}
3969
3970
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003971void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003972 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003973 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003974 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003975}
3976
3977ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3978 kPrototypeOrInitialMapOffset)
3979
3980
3981Map* JSFunction::initial_map() {
3982 return Map::cast(prototype_or_initial_map());
3983}
3984
3985
3986void JSFunction::set_initial_map(Map* value) {
3987 set_prototype_or_initial_map(value);
3988}
3989
3990
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003991MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
3992 Map* initial_map) {
3993 Context* global_context = context()->global_context();
3994 Object* array_function =
3995 global_context->get(Context::ARRAY_FUNCTION_INDEX);
3996 if (array_function->IsJSFunction() &&
3997 this == JSFunction::cast(array_function)) {
3998 ASSERT(initial_map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
3999
4000 MaybeObject* maybe_map = initial_map->CopyDropTransitions();
4001 Map* new_double_map = NULL;
4002 if (!maybe_map->To<Map>(&new_double_map)) return maybe_map;
4003 new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004004 maybe_map = initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS,
4005 new_double_map);
4006 if (maybe_map->IsFailure()) return maybe_map;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004007
4008 maybe_map = new_double_map->CopyDropTransitions();
4009 Map* new_object_map = NULL;
4010 if (!maybe_map->To<Map>(&new_object_map)) return maybe_map;
4011 new_object_map->set_elements_kind(FAST_ELEMENTS);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004012 maybe_map = new_double_map->AddElementsTransition(FAST_ELEMENTS,
4013 new_object_map);
4014 if (maybe_map->IsFailure()) return maybe_map;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004015
4016 global_context->set_smi_js_array_map(initial_map);
4017 global_context->set_double_js_array_map(new_double_map);
4018 global_context->set_object_js_array_map(new_object_map);
4019 }
4020 set_initial_map(initial_map);
4021 return this;
4022}
4023
4024
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004025bool JSFunction::has_initial_map() {
4026 return prototype_or_initial_map()->IsMap();
4027}
4028
4029
4030bool JSFunction::has_instance_prototype() {
4031 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4032}
4033
4034
4035bool JSFunction::has_prototype() {
4036 return map()->has_non_instance_prototype() || has_instance_prototype();
4037}
4038
4039
4040Object* JSFunction::instance_prototype() {
4041 ASSERT(has_instance_prototype());
4042 if (has_initial_map()) return initial_map()->prototype();
4043 // When there is no initial map and the prototype is a JSObject, the
4044 // initial map field is used for the prototype field.
4045 return prototype_or_initial_map();
4046}
4047
4048
4049Object* JSFunction::prototype() {
4050 ASSERT(has_prototype());
4051 // If the function's prototype property has been set to a non-JSObject
4052 // value, that value is stored in the constructor field of the map.
4053 if (map()->has_non_instance_prototype()) return map()->constructor();
4054 return instance_prototype();
4055}
4056
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00004057bool JSFunction::should_have_prototype() {
4058 return map()->function_with_prototype();
4059}
4060
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004061
4062bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004063 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004064}
4065
4066
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004067FixedArray* JSFunction::literals() {
4068 ASSERT(!shared()->bound());
4069 return literals_or_bindings();
4070}
4071
4072
4073void JSFunction::set_literals(FixedArray* literals) {
4074 ASSERT(!shared()->bound());
4075 set_literals_or_bindings(literals);
4076}
4077
4078
4079FixedArray* JSFunction::function_bindings() {
4080 ASSERT(shared()->bound());
4081 return literals_or_bindings();
4082}
4083
4084
4085void JSFunction::set_function_bindings(FixedArray* bindings) {
4086 ASSERT(shared()->bound());
4087 // Bound function literal may be initialized to the empty fixed array
4088 // before the bindings are set.
4089 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4090 bindings->map() == GetHeap()->fixed_cow_array_map());
4091 set_literals_or_bindings(bindings);
4092}
4093
4094
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004095int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004096 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004097 return literals()->length();
4098}
4099
4100
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004101Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004102 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004103 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004104}
4105
4106
4107void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4108 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004109 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004110 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004111 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004112}
4113
4114
4115Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004116 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004117 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4118}
4119
4120
4121void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4122 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004123 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004124 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004125 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004126}
4127
4128
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004129ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004130ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004131ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4132ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4133
4134
4135void JSProxy::InitializeBody(int object_size, Object* value) {
4136 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4137 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4138 WRITE_FIELD(this, offset, value);
4139 }
4140}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004141
4142
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004143ACCESSORS(JSSet, table, Object, kTableOffset)
4144ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004145ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4146ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004147
4148
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004149Address Foreign::foreign_address() {
4150 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004151}
4152
4153
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004154void Foreign::set_foreign_address(Address value) {
4155 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004156}
4157
4158
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004159ACCESSORS(JSModule, context, Object, kContextOffset)
4160
4161
4162JSModule* JSModule::cast(Object* obj) {
4163 ASSERT(obj->IsJSModule());
4164 ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
4165 return reinterpret_cast<JSModule*>(obj);
4166}
4167
4168
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004169ACCESSORS(JSValue, value, Object, kValueOffset)
4170
4171
4172JSValue* JSValue::cast(Object* obj) {
4173 ASSERT(obj->IsJSValue());
4174 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4175 return reinterpret_cast<JSValue*>(obj);
4176}
4177
4178
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004179ACCESSORS(JSDate, value, Object, kValueOffset)
4180ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4181ACCESSORS(JSDate, year, Object, kYearOffset)
4182ACCESSORS(JSDate, month, Object, kMonthOffset)
4183ACCESSORS(JSDate, day, Object, kDayOffset)
4184ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4185ACCESSORS(JSDate, hour, Object, kHourOffset)
4186ACCESSORS(JSDate, min, Object, kMinOffset)
4187ACCESSORS(JSDate, sec, Object, kSecOffset)
4188
4189
4190JSDate* JSDate::cast(Object* obj) {
4191 ASSERT(obj->IsJSDate());
4192 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4193 return reinterpret_cast<JSDate*>(obj);
4194}
4195
4196
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004197ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4198ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4199ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4200ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4201ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4202SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4203SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4204
4205
4206JSMessageObject* JSMessageObject::cast(Object* obj) {
4207 ASSERT(obj->IsJSMessageObject());
4208 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4209 return reinterpret_cast<JSMessageObject*>(obj);
4210}
4211
4212
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004213INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004214ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004215ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004216ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004217ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004218ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00004219INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004220
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004221byte* Code::instruction_start() {
4222 return FIELD_ADDR(this, kHeaderSize);
4223}
4224
4225
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004226byte* Code::instruction_end() {
4227 return instruction_start() + instruction_size();
4228}
4229
4230
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004231int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004232 return RoundUp(instruction_size(), kObjectAlignment);
4233}
4234
4235
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004236FixedArray* Code::unchecked_deoptimization_data() {
4237 return reinterpret_cast<FixedArray*>(
4238 READ_FIELD(this, kDeoptimizationDataOffset));
4239}
4240
4241
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004242ByteArray* Code::unchecked_relocation_info() {
4243 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004244}
4245
4246
4247byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004248 return unchecked_relocation_info()->GetDataStartAddress();
4249}
4250
4251
4252int Code::relocation_size() {
4253 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004254}
4255
4256
4257byte* Code::entry() {
4258 return instruction_start();
4259}
4260
4261
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004262bool Code::contains(byte* inner_pointer) {
4263 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004264}
4265
4266
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004267ACCESSORS(JSArray, length, Object, kLengthOffset)
4268
4269
ager@chromium.org236ad962008-09-25 09:45:57 +00004270ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004271
4272
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004273JSRegExp::Type JSRegExp::TypeTag() {
4274 Object* data = this->data();
4275 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4276 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4277 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004278}
4279
4280
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004281JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4282 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4283 return static_cast<JSRegExp::Type>(smi->value());
4284}
4285
4286
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004287int JSRegExp::CaptureCount() {
4288 switch (TypeTag()) {
4289 case ATOM:
4290 return 0;
4291 case IRREGEXP:
4292 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4293 default:
4294 UNREACHABLE();
4295 return -1;
4296 }
4297}
4298
4299
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004300JSRegExp::Flags JSRegExp::GetFlags() {
4301 ASSERT(this->data()->IsFixedArray());
4302 Object* data = this->data();
4303 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4304 return Flags(smi->value());
4305}
4306
4307
4308String* JSRegExp::Pattern() {
4309 ASSERT(this->data()->IsFixedArray());
4310 Object* data = this->data();
4311 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4312 return pattern;
4313}
4314
4315
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004316Object* JSRegExp::DataAt(int index) {
4317 ASSERT(TypeTag() != NOT_COMPILED);
4318 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004319}
4320
4321
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004322Object* JSRegExp::DataAtUnchecked(int index) {
4323 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4324 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4325 return READ_FIELD(fa, offset);
4326}
4327
4328
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004329void JSRegExp::SetDataAt(int index, Object* value) {
4330 ASSERT(TypeTag() != NOT_COMPILED);
4331 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4332 FixedArray::cast(data())->set(index, value);
4333}
4334
4335
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004336void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4337 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4338 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4339 if (value->IsSmi()) {
4340 fa->set_unchecked(index, Smi::cast(value));
4341 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004342 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004343 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4344 }
4345}
4346
4347
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004348ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004349 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004350#if DEBUG
4351 FixedArrayBase* fixed_array =
4352 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4353 Map* map = fixed_array->map();
4354 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004355 (map == GetHeap()->fixed_array_map() ||
4356 map == GetHeap()->fixed_cow_array_map())) ||
4357 (kind == FAST_DOUBLE_ELEMENTS &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004358 (fixed_array->IsFixedDoubleArray() ||
4359 fixed_array == GetHeap()->empty_fixed_array())) ||
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004360 (kind == DICTIONARY_ELEMENTS &&
4361 fixed_array->IsFixedArray() &&
4362 fixed_array->IsDictionary()) ||
4363 (kind > DICTIONARY_ELEMENTS));
4364 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4365 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004366#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004367 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004368}
4369
4370
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004371ElementsAccessor* JSObject::GetElementsAccessor() {
4372 return ElementsAccessor::ForKind(GetElementsKind());
4373}
4374
4375
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004376bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004377 return GetElementsKind() == FAST_ELEMENTS;
4378}
4379
4380
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004381bool JSObject::HasFastSmiOnlyElements() {
4382 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4383}
4384
4385
4386bool JSObject::HasFastTypeElements() {
4387 ElementsKind elements_kind = GetElementsKind();
4388 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4389 elements_kind == FAST_ELEMENTS;
4390}
4391
4392
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004393bool JSObject::HasFastDoubleElements() {
4394 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4395}
4396
4397
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004398bool JSObject::HasDictionaryElements() {
4399 return GetElementsKind() == DICTIONARY_ELEMENTS;
4400}
4401
4402
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004403bool JSObject::HasNonStrictArgumentsElements() {
4404 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4405}
4406
4407
ager@chromium.org3811b432009-10-28 14:53:37 +00004408bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004409 HeapObject* array = elements();
4410 ASSERT(array != NULL);
4411 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004412}
4413
4414
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004415#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4416bool JSObject::HasExternal##name##Elements() { \
4417 HeapObject* array = elements(); \
4418 ASSERT(array != NULL); \
4419 if (!array->IsHeapObject()) \
4420 return false; \
4421 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004422}
4423
4424
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004425EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4426EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4427EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4428EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4429 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4430EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4431EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4432 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4433EXTERNAL_ELEMENTS_CHECK(Float,
4434 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004435EXTERNAL_ELEMENTS_CHECK(Double,
4436 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004437EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004438
4439
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004440bool JSObject::HasNamedInterceptor() {
4441 return map()->has_named_interceptor();
4442}
4443
4444
4445bool JSObject::HasIndexedInterceptor() {
4446 return map()->has_indexed_interceptor();
4447}
4448
4449
lrn@chromium.org303ada72010-10-27 09:33:13 +00004450MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004451 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004452 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004453 Isolate* isolate = GetIsolate();
4454 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004455 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004456 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4457 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004458 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4459 return maybe_writable_elems;
4460 }
4461 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004462 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004463 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004464 return writable_elems;
4465}
4466
4467
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004468StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004469 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004470 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004471}
4472
4473
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004474SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004475 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004476 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004477}
4478
4479
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004480bool String::IsHashFieldComputed(uint32_t field) {
4481 return (field & kHashNotComputedMask) == 0;
4482}
4483
4484
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004485bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004486 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004487}
4488
4489
4490uint32_t String::Hash() {
4491 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004492 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004493 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004494 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004495 return ComputeAndSetHash();
4496}
4497
4498
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004499StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004500 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004501 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004502 array_index_(0),
4503 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4504 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004505 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004506 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004507}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004508
4509
4510bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004511 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004512}
4513
4514
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004515void StringHasher::AddCharacter(uint32_t c) {
4516 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4517 AddSurrogatePair(c); // Not inlined.
4518 return;
4519 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004520 // Use the Jenkins one-at-a-time hash function to update the hash
4521 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004522 raw_running_hash_ += c;
4523 raw_running_hash_ += (raw_running_hash_ << 10);
4524 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004525 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004526 if (is_array_index_) {
4527 if (c < '0' || c > '9') {
4528 is_array_index_ = false;
4529 } else {
4530 int d = c - '0';
4531 if (is_first_char_) {
4532 is_first_char_ = false;
4533 if (c == '0' && length_ > 1) {
4534 is_array_index_ = false;
4535 return;
4536 }
4537 }
4538 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4539 is_array_index_ = false;
4540 } else {
4541 array_index_ = array_index_ * 10 + d;
4542 }
4543 }
4544 }
4545}
4546
4547
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004548void StringHasher::AddCharacterNoIndex(uint32_t c) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00004549 ASSERT(!is_array_index());
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004550 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4551 AddSurrogatePairNoIndex(c); // Not inlined.
4552 return;
4553 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004554 raw_running_hash_ += c;
4555 raw_running_hash_ += (raw_running_hash_ << 10);
4556 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4557}
4558
4559
4560uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004561 // Get the calculated raw hash value and do some more bit ops to distribute
4562 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004563 uint32_t result = raw_running_hash_;
4564 result += (result << 3);
4565 result ^= (result >> 11);
4566 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004567 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004568 result = 27;
4569 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004570 return result;
4571}
4572
4573
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004574template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004575uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4576 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004577 if (!hasher.has_trivial_hash()) {
4578 int i;
4579 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4580 hasher.AddCharacter(chars[i]);
4581 }
4582 for (; i < length; i++) {
4583 hasher.AddCharacterNoIndex(chars[i]);
4584 }
4585 }
4586 return hasher.GetHashField();
4587}
4588
4589
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004590bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004591 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004592 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4593 return false;
4594 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004595 return SlowAsArrayIndex(index);
4596}
4597
4598
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004599Object* JSReceiver::GetPrototype() {
4600 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004601}
4602
4603
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004604bool JSReceiver::HasProperty(String* name) {
4605 if (IsJSProxy()) {
4606 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4607 }
4608 return GetPropertyAttribute(name) != ABSENT;
4609}
4610
4611
4612bool JSReceiver::HasLocalProperty(String* name) {
4613 if (IsJSProxy()) {
4614 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4615 }
4616 return GetLocalPropertyAttribute(name) != ABSENT;
4617}
4618
4619
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004620PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004621 return GetPropertyAttributeWithReceiver(this, key);
4622}
4623
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004624// TODO(504): this may be useful in other places too where JSGlobalProxy
4625// is used.
4626Object* JSObject::BypassGlobalProxy() {
4627 if (IsJSGlobalProxy()) {
4628 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004629 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004630 ASSERT(proto->IsJSGlobalObject());
4631 return proto;
4632 }
4633 return this;
4634}
4635
4636
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004637MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4638 return IsJSProxy()
4639 ? JSProxy::cast(this)->GetIdentityHash(flag)
4640 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004641}
4642
4643
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004644bool JSReceiver::HasElement(uint32_t index) {
4645 if (IsJSProxy()) {
4646 return JSProxy::cast(this)->HasElementWithHandler(index);
4647 }
4648 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004649}
4650
4651
4652bool AccessorInfo::all_can_read() {
4653 return BooleanBit::get(flag(), kAllCanReadBit);
4654}
4655
4656
4657void AccessorInfo::set_all_can_read(bool value) {
4658 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4659}
4660
4661
4662bool AccessorInfo::all_can_write() {
4663 return BooleanBit::get(flag(), kAllCanWriteBit);
4664}
4665
4666
4667void AccessorInfo::set_all_can_write(bool value) {
4668 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4669}
4670
4671
ager@chromium.org870a0b62008-11-04 11:43:05 +00004672bool AccessorInfo::prohibits_overwriting() {
4673 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4674}
4675
4676
4677void AccessorInfo::set_prohibits_overwriting(bool value) {
4678 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4679}
4680
4681
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004682PropertyAttributes AccessorInfo::property_attributes() {
4683 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4684}
4685
4686
4687void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004688 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004689}
4690
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004691
4692template<typename Shape, typename Key>
4693void Dictionary<Shape, Key>::SetEntry(int entry,
4694 Object* key,
4695 Object* value) {
4696 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4697}
4698
4699
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004700template<typename Shape, typename Key>
4701void Dictionary<Shape, Key>::SetEntry(int entry,
4702 Object* key,
4703 Object* value,
4704 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004705 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004706 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004707 AssertNoAllocation no_gc;
4708 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004709 FixedArray::set(index, key, mode);
4710 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004711 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004712}
4713
4714
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004715bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4716 ASSERT(other->IsNumber());
4717 return key == static_cast<uint32_t>(other->Number());
4718}
4719
4720
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004721uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
4722 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004723}
4724
4725
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004726uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
4727 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004728 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004729 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004730}
4731
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004732uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
4733 return ComputeIntegerHash(key, seed);
4734}
4735
4736uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
4737 uint32_t seed,
4738 Object* other) {
4739 ASSERT(other->IsNumber());
4740 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
4741}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004742
4743MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4744 return Isolate::Current()->heap()->NumberFromUint32(key);
4745}
4746
4747
4748bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4749 // We know that all entries in a hash table had their hash keys created.
4750 // Use that knowledge to have fast failure.
4751 if (key->Hash() != String::cast(other)->Hash()) return false;
4752 return key->Equals(String::cast(other));
4753}
4754
4755
4756uint32_t StringDictionaryShape::Hash(String* key) {
4757 return key->Hash();
4758}
4759
4760
4761uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4762 return String::cast(other)->Hash();
4763}
4764
4765
4766MaybeObject* StringDictionaryShape::AsObject(String* key) {
4767 return key;
4768}
4769
4770
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004771template <int entrysize>
4772bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4773 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004774}
4775
4776
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004777template <int entrysize>
4778uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004779 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4780 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004781}
4782
4783
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004784template <int entrysize>
4785uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4786 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004787 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4788 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004789}
4790
4791
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004792template <int entrysize>
4793MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004794 return key;
4795}
4796
4797
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004798void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004799 // No write barrier is needed since empty_fixed_array is not in new space.
4800 // Please note this function is used during marking:
4801 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00004802 // - IncrementalMarking::Step
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004803 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4804 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004805}
4806
4807
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004808void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004809 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004810 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004811 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4812 if (elts->length() < required_size) {
4813 // Doubling in size would be overkill, but leave some slack to avoid
4814 // constantly growing.
4815 Expand(required_size + (required_size >> 3));
4816 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004817 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004818 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4819 // Expand will allocate a new backing store in new space even if the size
4820 // we asked for isn't larger than what we had before.
4821 Expand(required_size);
4822 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004823}
4824
4825
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004826void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004827 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004828 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4829}
4830
4831
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004832bool JSArray::AllowsSetElementsLength() {
4833 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4834 ASSERT(result == !HasExternalArrayElements());
4835 return result;
4836}
4837
4838
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004839MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4840 MaybeObject* maybe_result = EnsureCanContainElements(
4841 storage, ALLOW_COPIED_DOUBLE_ELEMENTS);
4842 if (maybe_result->IsFailure()) return maybe_result;
4843 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4844 GetElementsKind() == FAST_DOUBLE_ELEMENTS) ||
4845 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4846 ((GetElementsKind() == FAST_ELEMENTS) ||
4847 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS &&
4848 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004849 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004850 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004851 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004852}
4853
4854
lrn@chromium.org303ada72010-10-27 09:33:13 +00004855MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004856 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004857 return GetHeap()->CopyFixedArray(this);
4858}
4859
4860
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004861MaybeObject* FixedDoubleArray::Copy() {
4862 if (length() == 0) return this;
4863 return GetHeap()->CopyFixedDoubleArray(this);
4864}
4865
4866
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004867void TypeFeedbackCells::SetAstId(int index, Smi* id) {
4868 set(1 + index * 2, id);
4869}
4870
4871
4872Smi* TypeFeedbackCells::AstId(int index) {
4873 return Smi::cast(get(1 + index * 2));
4874}
4875
4876
4877void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
4878 set(index * 2, cell);
4879}
4880
4881
4882JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
4883 return JSGlobalPropertyCell::cast(get(index * 2));
4884}
4885
4886
4887Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
4888 return isolate->factory()->the_hole_value();
4889}
4890
4891
4892Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
4893 return isolate->factory()->undefined_value();
4894}
4895
4896
4897Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
4898 return heap->raw_unchecked_the_hole_value();
4899}
4900
4901
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004902SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00004903SMI_ACCESSORS(TypeFeedbackInfo, ic_with_type_info_count,
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004904 kIcWithTypeinfoCountOffset)
4905ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
4906 kTypeFeedbackCellsOffset)
4907
4908
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00004909SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
4910
4911
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004912Relocatable::Relocatable(Isolate* isolate) {
4913 ASSERT(isolate == Isolate::Current());
4914 isolate_ = isolate;
4915 prev_ = isolate->relocatable_top();
4916 isolate->set_relocatable_top(this);
4917}
4918
4919
4920Relocatable::~Relocatable() {
4921 ASSERT(isolate_ == Isolate::Current());
4922 ASSERT_EQ(isolate_->relocatable_top(), this);
4923 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004924}
4925
4926
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004927int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4928 return map->instance_size();
4929}
4930
4931
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004932void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004933 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004934 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004935}
4936
4937
4938template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004939void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004940 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004941 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004942}
4943
4944
4945void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4946 typedef v8::String::ExternalAsciiStringResource Resource;
4947 v->VisitExternalAsciiString(
4948 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4949}
4950
4951
4952template<typename StaticVisitor>
4953void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4954 typedef v8::String::ExternalAsciiStringResource Resource;
4955 StaticVisitor::VisitExternalAsciiString(
4956 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4957}
4958
4959
4960void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4961 typedef v8::String::ExternalStringResource Resource;
4962 v->VisitExternalTwoByteString(
4963 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4964}
4965
4966
4967template<typename StaticVisitor>
4968void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4969 typedef v8::String::ExternalStringResource Resource;
4970 StaticVisitor::VisitExternalTwoByteString(
4971 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4972}
4973
4974#define SLOT_ADDR(obj, offset) \
4975 reinterpret_cast<Object**>((obj)->address() + offset)
4976
4977template<int start_offset, int end_offset, int size>
4978void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4979 HeapObject* obj,
4980 ObjectVisitor* v) {
4981 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4982}
4983
4984
4985template<int start_offset>
4986void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4987 int object_size,
4988 ObjectVisitor* v) {
4989 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4990}
4991
4992#undef SLOT_ADDR
4993
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004994#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004995#undef CAST_ACCESSOR
4996#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004997#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004998#undef ACCESSORS_TO_SMI
4999#undef SMI_ACCESSORS
5000#undef BOOL_GETTER
5001#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005002#undef FIELD_ADDR
5003#undef READ_FIELD
5004#undef WRITE_FIELD
5005#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005006#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005007#undef READ_DOUBLE_FIELD
5008#undef WRITE_DOUBLE_FIELD
5009#undef READ_INT_FIELD
5010#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005011#undef READ_INTPTR_FIELD
5012#undef WRITE_INTPTR_FIELD
5013#undef READ_UINT32_FIELD
5014#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005015#undef READ_SHORT_FIELD
5016#undef WRITE_SHORT_FIELD
5017#undef READ_BYTE_FIELD
5018#undef WRITE_BYTE_FIELD
5019
5020
5021} } // namespace v8::internal
5022
5023#endif // V8_OBJECTS_INL_H_