blob: 55a3b2ff40d247e73d1c7fdf1d1c8d7c9751d708 [file] [log] [blame]
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001// Copyright 2011 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"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000048
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
97#define SMI_ACCESSORS(holder, name, offset) \
98 int holder::name() { \
99 Object* value = READ_FIELD(this, offset); \
100 return Smi::cast(value)->value(); \
101 } \
102 void holder::set_##name(int value) { \
103 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
104 }
105
106
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000107#define BOOL_GETTER(holder, field, name, offset) \
108 bool holder::name() { \
109 return BooleanBit::get(field(), offset); \
110 } \
111
112
113#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000114 bool holder::name() { \
115 return BooleanBit::get(field(), offset); \
116 } \
117 void holder::set_##name(bool value) { \
118 set_##field(BooleanBit::set(field(), offset, value)); \
119 }
120
121
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000122bool Object::IsFixedArrayBase() {
123 return IsFixedArray() || IsFixedDoubleArray();
124}
125
126
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000127bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
128 // There is a constraint on the object; check.
129 if (!this->IsJSObject()) return false;
130 // Fetch the constructor function of the object.
131 Object* cons_obj = JSObject::cast(this)->map()->constructor();
132 if (!cons_obj->IsJSFunction()) return false;
133 JSFunction* fun = JSFunction::cast(cons_obj);
134 // Iterate through the chain of inheriting function templates to
135 // see if the required one occurs.
136 for (Object* type = fun->shared()->function_data();
137 type->IsFunctionTemplateInfo();
138 type = FunctionTemplateInfo::cast(type)->parent_template()) {
139 if (type == expected) return true;
140 }
141 // Didn't find the required type in the inheritance chain.
142 return false;
143}
144
145
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000146bool Object::IsSmi() {
147 return HAS_SMI_TAG(this);
148}
149
150
151bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000152 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000153}
154
155
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000156bool Object::NonFailureIsHeapObject() {
157 ASSERT(!this->IsFailure());
158 return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0;
159}
160
161
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000162TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000163
164
165bool Object::IsString() {
166 return Object::IsHeapObject()
167 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
168}
169
170
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000171bool Object::IsSpecObject() {
172 return Object::IsHeapObject()
173 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
174}
175
176
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000177bool Object::IsSpecFunction() {
178 if (!Object::IsHeapObject()) return false;
179 InstanceType type = HeapObject::cast(this)->map()->instance_type();
180 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
181}
182
183
ager@chromium.org870a0b62008-11-04 11:43:05 +0000184bool Object::IsSymbol() {
185 if (!this->IsHeapObject()) return false;
186 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000187 // Because the symbol tag is non-zero and no non-string types have the
188 // symbol bit set we can test for symbols with a very simple test
189 // operation.
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000190 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000191 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
192 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000193}
194
195
196bool Object::IsConsString() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000197 if (!IsString()) return false;
198 return StringShape(String::cast(this)).IsCons();
199}
200
201
202bool Object::IsSlicedString() {
203 if (!IsString()) return false;
204 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000205}
206
207
ager@chromium.org870a0b62008-11-04 11:43:05 +0000208bool Object::IsSeqString() {
209 if (!IsString()) return false;
210 return StringShape(String::cast(this)).IsSequential();
211}
212
213
214bool Object::IsSeqAsciiString() {
215 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000216 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000217 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000218}
219
220
221bool Object::IsSeqTwoByteString() {
222 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000223 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000224 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000225}
226
227
228bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000229 if (!IsString()) return false;
230 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000231}
232
233
234bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000235 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000236 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000237 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000238}
239
240
241bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000242 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000243 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000244 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000245}
246
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000247bool Object::HasValidElements() {
248 // Dictionary is covered under FixedArray.
249 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
250}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000251
ager@chromium.org870a0b62008-11-04 11:43:05 +0000252StringShape::StringShape(String* str)
253 : type_(str->map()->instance_type()) {
254 set_valid();
255 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000256}
257
258
ager@chromium.org870a0b62008-11-04 11:43:05 +0000259StringShape::StringShape(Map* map)
260 : type_(map->instance_type()) {
261 set_valid();
262 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000263}
264
265
ager@chromium.org870a0b62008-11-04 11:43:05 +0000266StringShape::StringShape(InstanceType t)
267 : type_(static_cast<uint32_t>(t)) {
268 set_valid();
269 ASSERT((type_ & kIsNotStringMask) == kStringTag);
270}
271
272
273bool StringShape::IsSymbol() {
274 ASSERT(valid());
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000275 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000276 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000277}
278
279
ager@chromium.org5ec48922009-05-05 07:25:34 +0000280bool String::IsAsciiRepresentation() {
281 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000282 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000283}
284
285
ager@chromium.org5ec48922009-05-05 07:25:34 +0000286bool String::IsTwoByteRepresentation() {
287 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000288 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000289}
290
291
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000292bool String::IsAsciiRepresentationUnderneath() {
293 uint32_t type = map()->instance_type();
294 STATIC_ASSERT(kIsIndirectStringTag != 0);
295 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
296 ASSERT(IsFlat());
297 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
298 case kAsciiStringTag:
299 return true;
300 case kTwoByteStringTag:
301 return false;
302 default: // Cons or sliced string. Need to go deeper.
303 return GetUnderlying()->IsAsciiRepresentation();
304 }
305}
306
307
308bool String::IsTwoByteRepresentationUnderneath() {
309 uint32_t type = map()->instance_type();
310 STATIC_ASSERT(kIsIndirectStringTag != 0);
311 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
312 ASSERT(IsFlat());
313 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
314 case kAsciiStringTag:
315 return false;
316 case kTwoByteStringTag:
317 return true;
318 default: // Cons or sliced string. Need to go deeper.
319 return GetUnderlying()->IsTwoByteRepresentation();
320 }
321}
322
323
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000324bool String::HasOnlyAsciiChars() {
325 uint32_t type = map()->instance_type();
326 return (type & kStringEncodingMask) == kAsciiStringTag ||
327 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000328}
329
330
ager@chromium.org870a0b62008-11-04 11:43:05 +0000331bool StringShape::IsCons() {
332 return (type_ & kStringRepresentationMask) == kConsStringTag;
333}
334
335
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000336bool StringShape::IsSliced() {
337 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
338}
339
340
341bool StringShape::IsIndirect() {
342 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
343}
344
345
ager@chromium.org870a0b62008-11-04 11:43:05 +0000346bool StringShape::IsExternal() {
347 return (type_ & kStringRepresentationMask) == kExternalStringTag;
348}
349
350
351bool StringShape::IsSequential() {
352 return (type_ & kStringRepresentationMask) == kSeqStringTag;
353}
354
355
356StringRepresentationTag StringShape::representation_tag() {
357 uint32_t tag = (type_ & kStringRepresentationMask);
358 return static_cast<StringRepresentationTag>(tag);
359}
360
361
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000362uint32_t StringShape::encoding_tag() {
363 return type_ & kStringEncodingMask;
364}
365
366
ager@chromium.org870a0b62008-11-04 11:43:05 +0000367uint32_t StringShape::full_representation_tag() {
368 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
369}
370
371
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000372STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
373 Internals::kFullStringRepresentationMask);
374
375
ager@chromium.org870a0b62008-11-04 11:43:05 +0000376bool StringShape::IsSequentialAscii() {
377 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
378}
379
380
381bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000382 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000383}
384
385
386bool StringShape::IsExternalAscii() {
387 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
388}
389
390
391bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000392 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000393}
394
395
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000396STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
397 Internals::kExternalTwoByteRepresentationTag);
398
399
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000400uc32 FlatStringReader::Get(int index) {
401 ASSERT(0 <= index && index <= length_);
402 if (is_ascii_) {
403 return static_cast<const byte*>(start_)[index];
404 } else {
405 return static_cast<const uc16*>(start_)[index];
406 }
407}
408
409
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000410bool Object::IsNumber() {
411 return IsSmi() || IsHeapNumber();
412}
413
414
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000415TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
416TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000417
418
419bool Object::IsFiller() {
420 if (!Object::IsHeapObject()) return false;
421 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
422 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
423}
424
425
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000426TYPE_CHECKER(ExternalPixelArray, EXTERNAL_PIXEL_ARRAY_TYPE)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000427
428
ager@chromium.org3811b432009-10-28 14:53:37 +0000429bool Object::IsExternalArray() {
430 if (!Object::IsHeapObject())
431 return false;
432 InstanceType instance_type =
433 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000434 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
435 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000436}
437
438
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000439TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE)
440TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
441TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE)
442TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
443TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE)
444TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
445TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE)
446TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000447
448
lrn@chromium.org303ada72010-10-27 09:33:13 +0000449bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000450 return HAS_FAILURE_TAG(this);
451}
452
453
lrn@chromium.org303ada72010-10-27 09:33:13 +0000454bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000455 return HAS_FAILURE_TAG(this)
456 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
457}
458
459
lrn@chromium.org303ada72010-10-27 09:33:13 +0000460bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000461 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000462 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000463}
464
465
lrn@chromium.org303ada72010-10-27 09:33:13 +0000466bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000467 return this == Failure::Exception();
468}
469
470
lrn@chromium.org303ada72010-10-27 09:33:13 +0000471bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000472 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000473}
474
475
476Failure* Failure::cast(MaybeObject* obj) {
477 ASSERT(HAS_FAILURE_TAG(obj));
478 return reinterpret_cast<Failure*>(obj);
479}
480
481
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000482bool Object::IsJSReceiver() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000483 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000484 return IsHeapObject() &&
485 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
486}
487
488
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000489bool Object::IsJSObject() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000490 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
491 return IsHeapObject() &&
492 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000493}
494
495
496bool Object::IsJSProxy() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000497 if (!Object::IsHeapObject()) return false;
498 InstanceType type = HeapObject::cast(this)->map()->instance_type();
499 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000500}
501
502
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000503TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
504TYPE_CHECKER(JSSet, JS_SET_TYPE)
505TYPE_CHECKER(JSMap, JS_MAP_TYPE)
506TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
507TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
508TYPE_CHECKER(Map, MAP_TYPE)
509TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
510TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000511
512
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000513bool Object::IsDescriptorArray() {
514 return IsFixedArray();
515}
516
517
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000518bool Object::IsDeoptimizationInputData() {
519 // Must be a fixed array.
520 if (!IsFixedArray()) return false;
521
522 // There's no sure way to detect the difference between a fixed array and
523 // a deoptimization data array. Since this is used for asserts we can
524 // check that the length is zero or else the fixed size plus a multiple of
525 // the entry size.
526 int length = FixedArray::cast(this)->length();
527 if (length == 0) return true;
528
529 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
530 return length >= 0 &&
531 length % DeoptimizationInputData::kDeoptEntrySize == 0;
532}
533
534
535bool Object::IsDeoptimizationOutputData() {
536 if (!IsFixedArray()) return false;
537 // There's actually no way to see the difference between a fixed array and
538 // a deoptimization data array. Since this is used for asserts we can check
539 // that the length is plausible though.
540 if (FixedArray::cast(this)->length() % 2 != 0) return false;
541 return true;
542}
543
544
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000545bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000546 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000547 Map* map = HeapObject::cast(this)->map();
548 Heap* heap = map->GetHeap();
549 return (map == heap->function_context_map() ||
550 map == heap->catch_context_map() ||
551 map == heap->with_context_map() ||
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000552 map == heap->global_context_map() ||
553 map == heap->block_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000554 }
555 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000556}
557
558
559bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000560 return Object::IsHeapObject() &&
561 HeapObject::cast(this)->map() ==
562 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000563}
564
565
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000566bool Object::IsScopeInfo() {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000567 return Object::IsHeapObject() &&
568 HeapObject::cast(this)->map() ==
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000569 HeapObject::cast(this)->GetHeap()->scope_info_map();
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000570}
571
572
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000573TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000574
575
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000576template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000577 return obj->IsJSFunction();
578}
579
580
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000581TYPE_CHECKER(Code, CODE_TYPE)
582TYPE_CHECKER(Oddball, ODDBALL_TYPE)
583TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
584TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
585TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
586TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000587
588
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000589bool Object::IsStringWrapper() {
590 return IsJSValue() && JSValue::cast(this)->value()->IsString();
591}
592
593
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000594TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000595
596
597bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000598 return IsOddball() &&
599 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000600}
601
602
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000603TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
604TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000605
606
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000607template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000608 return obj->IsJSArray();
609}
610
611
612bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000613 return Object::IsHeapObject() &&
614 HeapObject::cast(this)->map() ==
615 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000616}
617
618
619bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000620 return IsHashTable() &&
621 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000622}
623
624
625bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000626 return IsHashTable() && this ==
627 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000628}
629
630
ager@chromium.orgac091b72010-05-05 07:34:42 +0000631bool Object::IsJSFunctionResultCache() {
632 if (!IsFixedArray()) return false;
633 FixedArray* self = FixedArray::cast(this);
634 int length = self->length();
635 if (length < JSFunctionResultCache::kEntriesIndex) return false;
636 if ((length - JSFunctionResultCache::kEntriesIndex)
637 % JSFunctionResultCache::kEntrySize != 0) {
638 return false;
639 }
640#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000641 if (FLAG_verify_heap) {
642 reinterpret_cast<JSFunctionResultCache*>(this)->
643 JSFunctionResultCacheVerify();
644 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000645#endif
646 return true;
647}
648
649
ricow@chromium.org65fae842010-08-25 15:26:24 +0000650bool Object::IsNormalizedMapCache() {
651 if (!IsFixedArray()) return false;
652 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
653 return false;
654 }
655#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000656 if (FLAG_verify_heap) {
657 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
658 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000659#endif
660 return true;
661}
662
663
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000664bool Object::IsCompilationCacheTable() {
665 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000666}
667
668
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000669bool Object::IsCodeCacheHashTable() {
670 return IsHashTable();
671}
672
673
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000674bool Object::IsPolymorphicCodeCacheHashTable() {
675 return IsHashTable();
676}
677
678
ager@chromium.org236ad962008-09-25 09:45:57 +0000679bool Object::IsMapCache() {
680 return IsHashTable();
681}
682
683
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000684bool Object::IsPrimitive() {
685 return IsOddball() || IsNumber() || IsString();
686}
687
688
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000689bool Object::IsJSGlobalProxy() {
690 bool result = IsHeapObject() &&
691 (HeapObject::cast(this)->map()->instance_type() ==
692 JS_GLOBAL_PROXY_TYPE);
693 ASSERT(!result || IsAccessCheckNeeded());
694 return result;
695}
696
697
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000698bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000699 if (!IsHeapObject()) return false;
700
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000701 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000702 return type == JS_GLOBAL_OBJECT_TYPE ||
703 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000704}
705
706
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000707TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
708TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000709
710
711bool Object::IsUndetectableObject() {
712 return IsHeapObject()
713 && HeapObject::cast(this)->map()->is_undetectable();
714}
715
716
717bool Object::IsAccessCheckNeeded() {
718 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000719 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000720}
721
722
723bool Object::IsStruct() {
724 if (!IsHeapObject()) return false;
725 switch (HeapObject::cast(this)->map()->instance_type()) {
726#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
727 STRUCT_LIST(MAKE_STRUCT_CASE)
728#undef MAKE_STRUCT_CASE
729 default: return false;
730 }
731}
732
733
734#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
735 bool Object::Is##Name() { \
736 return Object::IsHeapObject() \
737 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
738 }
739 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
740#undef MAKE_STRUCT_PREDICATE
741
742
743bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000744 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000745}
746
747
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000748bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000749 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
750}
751
752
753bool Object::IsTheHole() {
754 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000755}
756
757
758bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000759 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000760}
761
762
763bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000764 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000765}
766
767
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000768bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000769 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000770}
771
772
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000773double Object::Number() {
774 ASSERT(IsNumber());
775 return IsSmi()
776 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
777 : reinterpret_cast<HeapNumber*>(this)->value();
778}
779
780
lrn@chromium.org303ada72010-10-27 09:33:13 +0000781MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000782 if (IsSmi()) return this;
783 if (IsHeapNumber()) {
784 double value = HeapNumber::cast(this)->value();
785 int int_value = FastD2I(value);
786 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
787 return Smi::FromInt(int_value);
788 }
789 }
790 return Failure::Exception();
791}
792
793
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000794bool Object::HasSpecificClassOf(String* name) {
795 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
796}
797
798
lrn@chromium.org303ada72010-10-27 09:33:13 +0000799MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000800 // GetElement can trigger a getter which can cause allocation.
801 // This was not always the case. This ASSERT is here to catch
802 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000803 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000804 return GetElementWithReceiver(this, index);
805}
806
807
lrn@chromium.org303ada72010-10-27 09:33:13 +0000808Object* Object::GetElementNoExceptionThrown(uint32_t index) {
809 MaybeObject* maybe = GetElementWithReceiver(this, index);
810 ASSERT(!maybe->IsFailure());
811 Object* result = NULL; // Initialization to please compiler.
812 maybe->ToObject(&result);
813 return result;
814}
815
816
817MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000818 PropertyAttributes attributes;
819 return GetPropertyWithReceiver(this, key, &attributes);
820}
821
822
lrn@chromium.org303ada72010-10-27 09:33:13 +0000823MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000824 return GetPropertyWithReceiver(this, key, attributes);
825}
826
827
828#define FIELD_ADDR(p, offset) \
829 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
830
831#define READ_FIELD(p, offset) \
832 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
833
834#define WRITE_FIELD(p, offset, value) \
835 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
836
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000837#define WRITE_BARRIER(heap, object, offset, value) \
838 heap->incremental_marking()->RecordWrite( \
839 object, HeapObject::RawField(object, offset), value); \
840 if (heap->InNewSpace(value)) { \
841 heap->RecordWrite(object->address(), offset); \
842 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000843
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000844#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
845 if (mode == UPDATE_WRITE_BARRIER) { \
846 heap->incremental_marking()->RecordWrite( \
847 object, HeapObject::RawField(object, offset), value); \
848 if (heap->InNewSpace(value)) { \
849 heap->RecordWrite(object->address(), offset); \
850 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000851 }
852
lrn@chromium.org7516f052011-03-30 08:52:27 +0000853#ifndef V8_TARGET_ARCH_MIPS
854 #define READ_DOUBLE_FIELD(p, offset) \
855 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
856#else // V8_TARGET_ARCH_MIPS
857 // Prevent gcc from using load-double (mips ldc1) on (possibly)
858 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000859 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000860 union conversion {
861 double d;
862 uint32_t u[2];
863 } c;
864 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
865 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
866 return c.d;
867 }
868 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
869#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000870
lrn@chromium.org7516f052011-03-30 08:52:27 +0000871#ifndef V8_TARGET_ARCH_MIPS
872 #define WRITE_DOUBLE_FIELD(p, offset, value) \
873 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
874#else // V8_TARGET_ARCH_MIPS
875 // Prevent gcc from using store-double (mips sdc1) on (possibly)
876 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000877 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000878 double value) {
879 union conversion {
880 double d;
881 uint32_t u[2];
882 } c;
883 c.d = value;
884 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
885 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
886 }
887 #define WRITE_DOUBLE_FIELD(p, offset, value) \
888 write_double_field(p, offset, value)
889#endif // V8_TARGET_ARCH_MIPS
890
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000891
892#define READ_INT_FIELD(p, offset) \
893 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
894
895#define WRITE_INT_FIELD(p, offset, value) \
896 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
897
ager@chromium.org3e875802009-06-29 08:26:34 +0000898#define READ_INTPTR_FIELD(p, offset) \
899 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
900
901#define WRITE_INTPTR_FIELD(p, offset, value) \
902 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
903
ager@chromium.org7c537e22008-10-16 08:43:32 +0000904#define READ_UINT32_FIELD(p, offset) \
905 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
906
907#define WRITE_UINT32_FIELD(p, offset, value) \
908 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
909
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000910#define READ_SHORT_FIELD(p, offset) \
911 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
912
913#define WRITE_SHORT_FIELD(p, offset, value) \
914 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
915
916#define READ_BYTE_FIELD(p, offset) \
917 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
918
919#define WRITE_BYTE_FIELD(p, offset, value) \
920 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
921
922
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000923Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
924 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000925}
926
927
928int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000929 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000930}
931
932
933Smi* Smi::FromInt(int value) {
934 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000935 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000936 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000937 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000938 return reinterpret_cast<Smi*>(tagged_value);
939}
940
941
942Smi* Smi::FromIntptr(intptr_t value) {
943 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000944 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
945 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000946}
947
948
949Failure::Type Failure::type() const {
950 return static_cast<Type>(value() & kFailureTypeTagMask);
951}
952
953
954bool Failure::IsInternalError() const {
955 return type() == INTERNAL_ERROR;
956}
957
958
959bool Failure::IsOutOfMemoryException() const {
960 return type() == OUT_OF_MEMORY_EXCEPTION;
961}
962
963
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000964AllocationSpace Failure::allocation_space() const {
965 ASSERT_EQ(RETRY_AFTER_GC, type());
966 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
967 & kSpaceTagMask);
968}
969
970
971Failure* Failure::InternalError() {
972 return Construct(INTERNAL_ERROR);
973}
974
975
976Failure* Failure::Exception() {
977 return Construct(EXCEPTION);
978}
979
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000980
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000981Failure* Failure::OutOfMemoryException() {
982 return Construct(OUT_OF_MEMORY_EXCEPTION);
983}
984
985
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000986intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000987 return static_cast<intptr_t>(
988 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000989}
990
991
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000992Failure* Failure::RetryAfterGC() {
993 return RetryAfterGC(NEW_SPACE);
994}
995
996
997Failure* Failure::RetryAfterGC(AllocationSpace space) {
998 ASSERT((space & ~kSpaceTagMask) == 0);
999 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001000}
1001
1002
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001003Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001004 uintptr_t info =
1005 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001006 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001007 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001008}
1009
1010
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001011bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001012#ifdef DEBUG
1013 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1014#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001015
1016#ifdef V8_TARGET_ARCH_X64
1017 // To be representable as a long smi, the value must be a 32-bit integer.
1018 bool result = (value == static_cast<int32_t>(value));
1019#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001020 // To be representable as an tagged small integer, the two
1021 // most-significant bits of 'value' must be either 00 or 11 due to
1022 // sign-extension. To check this we add 01 to the two
1023 // most-significant bits, and check if the most-significant bit is 0
1024 //
1025 // CAUTION: The original code below:
1026 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1027 // may lead to incorrect results according to the C language spec, and
1028 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1029 // compiler may produce undefined results in case of signed integer
1030 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001031 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001032#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001033 ASSERT(result == in_range);
1034 return result;
1035}
1036
1037
kasper.lund7276f142008-07-30 08:49:36 +00001038MapWord MapWord::FromMap(Map* map) {
1039 return MapWord(reinterpret_cast<uintptr_t>(map));
1040}
1041
1042
1043Map* MapWord::ToMap() {
1044 return reinterpret_cast<Map*>(value_);
1045}
1046
1047
1048bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001049 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001050}
1051
1052
1053MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001054 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1055 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001056}
1057
1058
1059HeapObject* MapWord::ToForwardingAddress() {
1060 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001061 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001062}
1063
1064
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001065#ifdef DEBUG
1066void HeapObject::VerifyObjectField(int offset) {
1067 VerifyPointer(READ_FIELD(this, offset));
1068}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001069
1070void HeapObject::VerifySmiField(int offset) {
1071 ASSERT(READ_FIELD(this, offset)->IsSmi());
1072}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001073#endif
1074
1075
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001076Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001077 Heap* heap =
1078 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1079 ASSERT(heap != NULL);
1080 ASSERT(heap->isolate() == Isolate::Current());
1081 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001082}
1083
1084
1085Isolate* HeapObject::GetIsolate() {
1086 return GetHeap()->isolate();
1087}
1088
1089
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001090Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001091 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001092}
1093
1094
1095void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001096 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001097 if (value != NULL) {
1098 // TODO(1600) We are passing NULL as a slot because maps can never be on
1099 // evacuation candidate.
1100 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1101 }
1102}
1103
1104
1105// Unsafe accessor omitting write barrier.
1106void HeapObject::set_map_unsafe(Map* value) {
1107 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001108}
1109
1110
kasper.lund7276f142008-07-30 08:49:36 +00001111MapWord HeapObject::map_word() {
1112 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1113}
1114
1115
1116void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001117 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001118 // here.
1119 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1120}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001121
1122
1123HeapObject* HeapObject::FromAddress(Address address) {
1124 ASSERT_TAG_ALIGNED(address);
1125 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1126}
1127
1128
1129Address HeapObject::address() {
1130 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1131}
1132
1133
1134int HeapObject::Size() {
1135 return SizeFromMap(map());
1136}
1137
1138
1139void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1140 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1141 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1142}
1143
1144
1145void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1146 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1147}
1148
1149
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001150double HeapNumber::value() {
1151 return READ_DOUBLE_FIELD(this, kValueOffset);
1152}
1153
1154
1155void HeapNumber::set_value(double value) {
1156 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1157}
1158
1159
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001160int HeapNumber::get_exponent() {
1161 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1162 kExponentShift) - kExponentBias;
1163}
1164
1165
1166int HeapNumber::get_sign() {
1167 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1168}
1169
1170
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001171ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001172
1173
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001174FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001175 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001176 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001177}
1178
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001179void JSObject::ValidateSmiOnlyElements() {
1180#if DEBUG
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001181 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001182 Heap* heap = GetHeap();
1183 // Don't use elements, since integrity checks will fail if there
1184 // are filler pointers in the array.
1185 FixedArray* fixed_array =
1186 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
1187 Map* map = fixed_array->map();
1188 // Arrays that have been shifted in place can't be verified.
1189 if (map != heap->raw_unchecked_one_pointer_filler_map() &&
1190 map != heap->raw_unchecked_two_pointer_filler_map() &&
1191 map != heap->free_space_map()) {
1192 for (int i = 0; i < fixed_array->length(); i++) {
1193 Object* current = fixed_array->get(i);
1194 ASSERT(current->IsSmi() || current == heap->the_hole_value());
1195 }
1196 }
1197 }
1198#endif
1199}
1200
1201
1202MaybeObject* JSObject::EnsureCanContainNonSmiElements() {
1203#if DEBUG
1204 ValidateSmiOnlyElements();
1205#endif
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001206 if ((map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS)) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001207 Object* obj;
1208 MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS);
1209 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1210 set_map(Map::cast(obj));
1211 }
1212 return this;
1213}
1214
1215
1216MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
1217 uint32_t count) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001218 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001219 for (uint32_t i = 0; i < count; ++i) {
1220 Object* current = *objects++;
1221 if (!current->IsSmi() && current != GetHeap()->the_hole_value()) {
1222 return EnsureCanContainNonSmiElements();
1223 }
1224 }
1225 }
1226 return this;
1227}
1228
1229
1230MaybeObject* JSObject::EnsureCanContainElements(FixedArray* elements) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001231 Object** objects = reinterpret_cast<Object**>(
1232 FIELD_ADDR(elements, elements->OffsetOfElementAt(0)));
1233 return EnsureCanContainElements(objects, elements->length());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001234}
1235
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001236
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001237void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001238 ASSERT((map()->has_fast_elements() ||
1239 map()->has_fast_smi_only_elements()) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001240 (value->map() == GetHeap()->fixed_array_map() ||
1241 value->map() == GetHeap()->fixed_cow_array_map()));
lrn@chromium.orgd4e9e222011-08-03 12:01:58 +00001242 ASSERT(map()->has_fast_double_elements() ==
1243 value->IsFixedDoubleArray());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001244 ASSERT(value->HasValidElements());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001245#ifdef DEBUG
1246 ValidateSmiOnlyElements();
1247#endif
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001248 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001249 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001250}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001251
1252
1253void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001254 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1255 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001256}
1257
1258
1259void JSObject::initialize_elements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001260 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001261 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1262 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001263}
1264
1265
lrn@chromium.org303ada72010-10-27 09:33:13 +00001266MaybeObject* JSObject::ResetElements() {
1267 Object* obj;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001268 ElementsKind elements_kind = FLAG_smi_only_arrays
1269 ? FAST_SMI_ONLY_ELEMENTS
1270 : FAST_ELEMENTS;
1271 MaybeObject* maybe_obj = GetElementsTransitionMap(elements_kind);
1272 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001273 set_map(Map::cast(obj));
1274 initialize_elements();
1275 return this;
1276}
1277
1278
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001279ACCESSORS(Oddball, to_string, String, kToStringOffset)
1280ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1281
1282
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001283byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001284 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001285}
1286
1287
1288void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001289 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001290}
1291
1292
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001293Object* JSGlobalPropertyCell::value() {
1294 return READ_FIELD(this, kValueOffset);
1295}
1296
1297
1298void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1299 // The write barrier is not used for global property cells.
1300 ASSERT(!val->IsJSGlobalPropertyCell());
1301 WRITE_FIELD(this, kValueOffset, val);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001302 GetHeap()->incremental_marking()->RecordWrite(
1303 this, HeapObject::RawField(this, kValueOffset), val);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001304}
1305
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001306
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001307int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001308 InstanceType type = map()->instance_type();
1309 // Check for the most common kind of JavaScript object before
1310 // falling into the generic switch. This speeds up the internal
1311 // field operations considerably on average.
1312 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1313 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001314 case JS_GLOBAL_PROXY_TYPE:
1315 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001316 case JS_GLOBAL_OBJECT_TYPE:
1317 return JSGlobalObject::kSize;
1318 case JS_BUILTINS_OBJECT_TYPE:
1319 return JSBuiltinsObject::kSize;
1320 case JS_FUNCTION_TYPE:
1321 return JSFunction::kSize;
1322 case JS_VALUE_TYPE:
1323 return JSValue::kSize;
1324 case JS_ARRAY_TYPE:
1325 return JSValue::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001326 case JS_WEAK_MAP_TYPE:
1327 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001328 case JS_REGEXP_TYPE:
1329 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001330 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001331 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001332 case JS_MESSAGE_OBJECT_TYPE:
1333 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001334 default:
1335 UNREACHABLE();
1336 return 0;
1337 }
1338}
1339
1340
1341int JSObject::GetInternalFieldCount() {
1342 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001343 // Make sure to adjust for the number of in-object properties. These
1344 // properties do contribute to the size, but are not internal fields.
1345 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1346 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001347}
1348
1349
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001350int JSObject::GetInternalFieldOffset(int index) {
1351 ASSERT(index < GetInternalFieldCount() && index >= 0);
1352 return GetHeaderSize() + (kPointerSize * index);
1353}
1354
1355
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001356Object* JSObject::GetInternalField(int index) {
1357 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001358 // Internal objects do follow immediately after the header, whereas in-object
1359 // properties are at the end of the object. Therefore there is no need
1360 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001361 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1362}
1363
1364
1365void JSObject::SetInternalField(int index, Object* value) {
1366 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001367 // Internal objects do follow immediately after the header, whereas in-object
1368 // properties are at the end of the object. Therefore there is no need
1369 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001370 int offset = GetHeaderSize() + (kPointerSize * index);
1371 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001372 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001373}
1374
1375
ager@chromium.org7c537e22008-10-16 08:43:32 +00001376// Access fast-case object properties at index. The use of these routines
1377// is needed to correctly distinguish between properties stored in-object and
1378// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001379Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001380 // Adjust for the number of properties stored in the object.
1381 index -= map()->inobject_properties();
1382 if (index < 0) {
1383 int offset = map()->instance_size() + (index * kPointerSize);
1384 return READ_FIELD(this, offset);
1385 } else {
1386 ASSERT(index < properties()->length());
1387 return properties()->get(index);
1388 }
1389}
1390
1391
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001392Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001393 // Adjust for the number of properties stored in the object.
1394 index -= map()->inobject_properties();
1395 if (index < 0) {
1396 int offset = map()->instance_size() + (index * kPointerSize);
1397 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001398 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001399 } else {
1400 ASSERT(index < properties()->length());
1401 properties()->set(index, value);
1402 }
1403 return value;
1404}
1405
1406
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001407int JSObject::GetInObjectPropertyOffset(int index) {
1408 // Adjust for the number of properties stored in the object.
1409 index -= map()->inobject_properties();
1410 ASSERT(index < 0);
1411 return map()->instance_size() + (index * kPointerSize);
1412}
1413
1414
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001415Object* JSObject::InObjectPropertyAt(int index) {
1416 // Adjust for the number of properties stored in the object.
1417 index -= map()->inobject_properties();
1418 ASSERT(index < 0);
1419 int offset = map()->instance_size() + (index * kPointerSize);
1420 return READ_FIELD(this, offset);
1421}
1422
1423
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001424Object* JSObject::InObjectPropertyAtPut(int index,
1425 Object* value,
1426 WriteBarrierMode mode) {
1427 // Adjust for the number of properties stored in the object.
1428 index -= map()->inobject_properties();
1429 ASSERT(index < 0);
1430 int offset = map()->instance_size() + (index * kPointerSize);
1431 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001432 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001433 return value;
1434}
1435
1436
1437
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001438void JSObject::InitializeBody(Map* map,
1439 Object* pre_allocated_value,
1440 Object* filler_value) {
1441 ASSERT(!filler_value->IsHeapObject() ||
1442 !GetHeap()->InNewSpace(filler_value));
1443 ASSERT(!pre_allocated_value->IsHeapObject() ||
1444 !GetHeap()->InNewSpace(pre_allocated_value));
1445 int size = map->instance_size();
1446 int offset = kHeaderSize;
1447 if (filler_value != pre_allocated_value) {
1448 int pre_allocated = map->pre_allocated_property_fields();
1449 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1450 for (int i = 0; i < pre_allocated; i++) {
1451 WRITE_FIELD(this, offset, pre_allocated_value);
1452 offset += kPointerSize;
1453 }
1454 }
1455 while (offset < size) {
1456 WRITE_FIELD(this, offset, filler_value);
1457 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001458 }
1459}
1460
1461
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001462bool JSObject::HasFastProperties() {
1463 return !properties()->IsDictionary();
1464}
1465
1466
1467int JSObject::MaxFastProperties() {
1468 // Allow extra fast properties if the object has more than
1469 // kMaxFastProperties in-object properties. When this is the case,
1470 // it is very unlikely that the object is being used as a dictionary
1471 // and there is a good chance that allowing more map transitions
1472 // will be worth it.
1473 return Max(map()->inobject_properties(), kMaxFastProperties);
1474}
1475
1476
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001477void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001478 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001479 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001480 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001481 }
1482}
1483
1484
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001485bool Object::ToArrayIndex(uint32_t* index) {
1486 if (IsSmi()) {
1487 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001488 if (value < 0) return false;
1489 *index = value;
1490 return true;
1491 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001492 if (IsHeapNumber()) {
1493 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001494 uint32_t uint_value = static_cast<uint32_t>(value);
1495 if (value == static_cast<double>(uint_value)) {
1496 *index = uint_value;
1497 return true;
1498 }
1499 }
1500 return false;
1501}
1502
1503
1504bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1505 if (!this->IsJSValue()) return false;
1506
1507 JSValue* js_value = JSValue::cast(this);
1508 if (!js_value->value()->IsString()) return false;
1509
1510 String* str = String::cast(js_value->value());
1511 if (index >= (uint32_t)str->length()) return false;
1512
1513 return true;
1514}
1515
1516
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001517FixedArrayBase* FixedArrayBase::cast(Object* object) {
1518 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1519 return reinterpret_cast<FixedArrayBase*>(object);
1520}
1521
1522
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001523Object* FixedArray::get(int index) {
1524 ASSERT(index >= 0 && index < this->length());
1525 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1526}
1527
1528
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001529void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001530 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001531 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001532 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1533 int offset = kHeaderSize + index * kPointerSize;
1534 WRITE_FIELD(this, offset, value);
1535}
1536
1537
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001538void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001539 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001540 ASSERT(index >= 0 && index < this->length());
1541 int offset = kHeaderSize + index * kPointerSize;
1542 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001543 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001544}
1545
1546
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001547inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1548 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1549}
1550
1551
1552inline double FixedDoubleArray::hole_nan_as_double() {
1553 return BitCast<double, uint64_t>(kHoleNanInt64);
1554}
1555
1556
1557inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1558 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1559 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1560 return OS::nan_value();
1561}
1562
1563
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001564double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001565 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1566 map() != HEAP->fixed_array_map());
1567 ASSERT(index >= 0 && index < this->length());
1568 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1569 ASSERT(!is_the_hole_nan(result));
1570 return result;
1571}
1572
1573
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001574MaybeObject* FixedDoubleArray::get(int index) {
1575 if (is_the_hole(index)) {
1576 return GetHeap()->the_hole_value();
1577 } else {
1578 return GetHeap()->NumberFromDouble(get_scalar(index));
1579 }
1580}
1581
1582
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001583void FixedDoubleArray::set(int index, double value) {
1584 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1585 map() != HEAP->fixed_array_map());
1586 int offset = kHeaderSize + index * kDoubleSize;
1587 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1588 WRITE_DOUBLE_FIELD(this, offset, value);
1589}
1590
1591
1592void FixedDoubleArray::set_the_hole(int index) {
1593 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1594 map() != HEAP->fixed_array_map());
1595 int offset = kHeaderSize + index * kDoubleSize;
1596 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1597}
1598
1599
1600bool FixedDoubleArray::is_the_hole(int index) {
1601 int offset = kHeaderSize + index * kDoubleSize;
1602 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1603}
1604
1605
1606void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1607 int old_length = from->length();
1608 ASSERT(old_length < length());
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001609 if (old_length * kDoubleSize >= OS::kMinComplexMemCopy) {
1610 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1611 FIELD_ADDR(from, kHeaderSize),
1612 old_length * kDoubleSize);
1613 } else {
1614 for (int i = 0; i < old_length; ++i) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001615 if (from->is_the_hole(i)) {
1616 set_the_hole(i);
1617 } else {
1618 set(i, from->get_scalar(i));
1619 }
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001620 }
1621 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001622 int offset = kHeaderSize + old_length * kDoubleSize;
1623 for (int current = from->length(); current < length(); ++current) {
1624 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1625 offset += kDoubleSize;
1626 }
1627}
1628
1629
1630void FixedDoubleArray::Initialize(FixedArray* from) {
1631 int old_length = from->length();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001632 ASSERT(old_length <= length());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001633 for (int i = 0; i < old_length; i++) {
1634 Object* hole_or_object = from->get(i);
1635 if (hole_or_object->IsTheHole()) {
1636 set_the_hole(i);
1637 } else {
1638 set(i, hole_or_object->Number());
1639 }
1640 }
1641 int offset = kHeaderSize + old_length * kDoubleSize;
1642 for (int current = from->length(); current < length(); ++current) {
1643 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1644 offset += kDoubleSize;
1645 }
1646}
1647
1648
1649void FixedDoubleArray::Initialize(NumberDictionary* from) {
1650 int offset = kHeaderSize;
1651 for (int current = 0; current < length(); ++current) {
1652 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1653 offset += kDoubleSize;
1654 }
1655 for (int i = 0; i < from->Capacity(); i++) {
1656 Object* key = from->KeyAt(i);
1657 if (key->IsNumber()) {
1658 uint32_t entry = static_cast<uint32_t>(key->Number());
1659 set(entry, from->ValueAt(i)->Number());
1660 }
1661 }
1662}
1663
1664
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001665WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001666 Heap* heap = GetHeap();
1667 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1668 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001669 return UPDATE_WRITE_BARRIER;
1670}
1671
1672
1673void FixedArray::set(int index,
1674 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001675 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001676 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001677 ASSERT(index >= 0 && index < this->length());
1678 int offset = kHeaderSize + index * kPointerSize;
1679 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001680 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001681}
1682
1683
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001684void FixedArray::NoWriteBarrierSet(FixedArray* array,
1685 int index,
1686 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001687 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001688 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001689 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001690 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1691}
1692
1693
1694void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001695 ASSERT(map() != HEAP->fixed_cow_array_map());
1696 set_undefined(GetHeap(), index);
1697}
1698
1699
1700void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001701 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001702 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001703 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001704 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001705}
1706
1707
ager@chromium.org236ad962008-09-25 09:45:57 +00001708void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001709 set_null(GetHeap(), index);
1710}
1711
1712
1713void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001714 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001715 ASSERT(!heap->InNewSpace(heap->null_value()));
1716 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001717}
1718
1719
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001720void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001721 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001722 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001723 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1724 WRITE_FIELD(this,
1725 kHeaderSize + index * kPointerSize,
1726 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001727}
1728
1729
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001730void FixedArray::set_unchecked(int index, Smi* value) {
1731 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1732 int offset = kHeaderSize + index * kPointerSize;
1733 WRITE_FIELD(this, offset, value);
1734}
1735
1736
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001737void FixedArray::set_unchecked(Heap* heap,
1738 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001739 Object* value,
1740 WriteBarrierMode mode) {
1741 int offset = kHeaderSize + index * kPointerSize;
1742 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001743 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001744}
1745
1746
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001747void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001748 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001749 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1750 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001751}
1752
1753
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001754Object** FixedArray::data_start() {
1755 return HeapObject::RawField(this, kHeaderSize);
1756}
1757
1758
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001759bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001760 ASSERT(this->IsSmi() ||
1761 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001762 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001763 return this->IsSmi() || length() <= kFirstIndex;
1764}
1765
1766
1767int DescriptorArray::bit_field3_storage() {
1768 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1769 return Smi::cast(storage)->value();
1770}
1771
1772void DescriptorArray::set_bit_field3_storage(int value) {
1773 ASSERT(!IsEmpty());
1774 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001775}
1776
1777
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001778void DescriptorArray::NoWriteBarrierSwap(FixedArray* array,
1779 int first,
1780 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001781 Object* tmp = array->get(first);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001782 NoWriteBarrierSet(array, first, array->get(second));
1783 NoWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001784}
1785
1786
1787int DescriptorArray::Search(String* name) {
1788 SLOW_ASSERT(IsSortedNoDuplicates());
1789
1790 // Check for empty descriptor array.
1791 int nof = number_of_descriptors();
1792 if (nof == 0) return kNotFound;
1793
1794 // Fast case: do linear search for small arrays.
1795 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001796 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001797 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001798 }
1799
1800 // Slow case: perform binary search.
1801 return BinarySearch(name, 0, nof - 1);
1802}
1803
1804
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001805int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001806 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001807 if (number == DescriptorLookupCache::kAbsent) {
1808 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001809 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001810 }
1811 return number;
1812}
1813
1814
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001815String* DescriptorArray::GetKey(int descriptor_number) {
1816 ASSERT(descriptor_number < number_of_descriptors());
1817 return String::cast(get(ToKeyIndex(descriptor_number)));
1818}
1819
1820
1821Object* DescriptorArray::GetValue(int descriptor_number) {
1822 ASSERT(descriptor_number < number_of_descriptors());
1823 return GetContentArray()->get(ToValueIndex(descriptor_number));
1824}
1825
1826
1827Smi* DescriptorArray::GetDetails(int descriptor_number) {
1828 ASSERT(descriptor_number < number_of_descriptors());
1829 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1830}
1831
1832
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001833PropertyType DescriptorArray::GetType(int descriptor_number) {
1834 ASSERT(descriptor_number < number_of_descriptors());
1835 return PropertyDetails(GetDetails(descriptor_number)).type();
1836}
1837
1838
1839int DescriptorArray::GetFieldIndex(int descriptor_number) {
1840 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1841}
1842
1843
1844JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1845 return JSFunction::cast(GetValue(descriptor_number));
1846}
1847
1848
1849Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1850 ASSERT(GetType(descriptor_number) == CALLBACKS);
1851 return GetValue(descriptor_number);
1852}
1853
1854
1855AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1856 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001857 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001858 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001859}
1860
1861
1862bool DescriptorArray::IsProperty(int descriptor_number) {
1863 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1864}
1865
1866
1867bool DescriptorArray::IsTransition(int descriptor_number) {
1868 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001869 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00001870 t == ELEMENTS_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001871}
1872
1873
1874bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1875 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1876}
1877
1878
1879bool DescriptorArray::IsDontEnum(int descriptor_number) {
1880 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1881}
1882
1883
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001884void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1885 desc->Init(GetKey(descriptor_number),
1886 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001887 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001888}
1889
1890
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001891void DescriptorArray::Set(int descriptor_number,
1892 Descriptor* desc,
1893 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001894 // Range check.
1895 ASSERT(descriptor_number < number_of_descriptors());
1896
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001897 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001898 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1899 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001900
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001901 NoWriteBarrierSet(this,
1902 ToKeyIndex(descriptor_number),
1903 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001904 FixedArray* content_array = GetContentArray();
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001905 NoWriteBarrierSet(content_array,
1906 ToValueIndex(descriptor_number),
1907 desc->GetValue());
1908 NoWriteBarrierSet(content_array,
1909 ToDetailsIndex(descriptor_number),
1910 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001911}
1912
1913
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001914void DescriptorArray::CopyFrom(int index,
1915 DescriptorArray* src,
1916 int src_index,
1917 const WhitenessWitness& witness) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001918 Descriptor desc;
1919 src->Get(src_index, &desc);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001920 Set(index, &desc, witness);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001921}
1922
1923
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001924void DescriptorArray::NoWriteBarrierSwapDescriptors(int first, int second) {
1925 NoWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001926 FixedArray* content_array = GetContentArray();
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001927 NoWriteBarrierSwap(content_array,
1928 ToValueIndex(first),
1929 ToValueIndex(second));
1930 NoWriteBarrierSwap(content_array,
1931 ToDetailsIndex(first),
1932 ToDetailsIndex(second));
1933}
1934
1935
1936DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
1937 : marking_(array->GetHeap()->incremental_marking()) {
1938 marking_->EnterNoMarkingScope();
1939 if (array->number_of_descriptors() > 0) {
1940 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
1941 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
1942 }
1943}
1944
1945
1946DescriptorArray::WhitenessWitness::~WhitenessWitness() {
1947 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001948}
1949
1950
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001951template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001952int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
1953 const int kMinCapacity = 32;
1954 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
1955 if (capacity < kMinCapacity) {
1956 capacity = kMinCapacity; // Guarantee min capacity.
1957 }
1958 return capacity;
1959}
1960
1961
1962template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001963int HashTable<Shape, Key>::FindEntry(Key key) {
1964 return FindEntry(GetIsolate(), key);
1965}
1966
1967
1968// Find entry for key otherwise return kNotFound.
1969template<typename Shape, typename Key>
1970int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
1971 uint32_t capacity = Capacity();
1972 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
1973 uint32_t count = 1;
1974 // EnsureCapacity will guarantee the hash table is never full.
1975 while (true) {
1976 Object* element = KeyAt(entry);
1977 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001978 if (element != isolate->heap()->the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001979 Shape::IsMatch(key, element)) return entry;
1980 entry = NextProbe(entry, count++, capacity);
1981 }
1982 return kNotFound;
1983}
1984
1985
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001986bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001987 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001988 if (!max_index_object->IsSmi()) return false;
1989 return 0 !=
1990 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1991}
1992
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001993uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001994 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001995 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001996 if (!max_index_object->IsSmi()) return 0;
1997 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1998 return value >> kRequiresSlowElementsTagSize;
1999}
2000
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002001void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002002 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002003}
2004
2005
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002006// ------------------------------------
2007// Cast operations
2008
2009
2010CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002011CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002012CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002013CAST_ACCESSOR(DeoptimizationInputData)
2014CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002015CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002016CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002017CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002018CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002019CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002020CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002021CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002022CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002023CAST_ACCESSOR(String)
2024CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002025CAST_ACCESSOR(SeqAsciiString)
2026CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002027CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002028CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002029CAST_ACCESSOR(ExternalString)
2030CAST_ACCESSOR(ExternalAsciiString)
2031CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002032CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002033CAST_ACCESSOR(JSObject)
2034CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002035CAST_ACCESSOR(HeapObject)
2036CAST_ACCESSOR(HeapNumber)
2037CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002038CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002039CAST_ACCESSOR(SharedFunctionInfo)
2040CAST_ACCESSOR(Map)
2041CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002042CAST_ACCESSOR(GlobalObject)
2043CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002044CAST_ACCESSOR(JSGlobalObject)
2045CAST_ACCESSOR(JSBuiltinsObject)
2046CAST_ACCESSOR(Code)
2047CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002048CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002049CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002050CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002051CAST_ACCESSOR(JSSet)
2052CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002053CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002054CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002055CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002056CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002057CAST_ACCESSOR(ExternalArray)
2058CAST_ACCESSOR(ExternalByteArray)
2059CAST_ACCESSOR(ExternalUnsignedByteArray)
2060CAST_ACCESSOR(ExternalShortArray)
2061CAST_ACCESSOR(ExternalUnsignedShortArray)
2062CAST_ACCESSOR(ExternalIntArray)
2063CAST_ACCESSOR(ExternalUnsignedIntArray)
2064CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002065CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002066CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002067CAST_ACCESSOR(Struct)
2068
2069
2070#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2071 STRUCT_LIST(MAKE_STRUCT_CAST)
2072#undef MAKE_STRUCT_CAST
2073
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002074
2075template <typename Shape, typename Key>
2076HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002077 ASSERT(obj->IsHashTable());
2078 return reinterpret_cast<HashTable*>(obj);
2079}
2080
2081
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002082SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002083SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002084
ager@chromium.orgac091b72010-05-05 07:34:42 +00002085SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002086
2087
2088uint32_t String::hash_field() {
2089 return READ_UINT32_FIELD(this, kHashFieldOffset);
2090}
2091
2092
2093void String::set_hash_field(uint32_t value) {
2094 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002095#if V8_HOST_ARCH_64_BIT
2096 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2097#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002098}
2099
2100
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002101bool String::Equals(String* other) {
2102 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002103 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2104 return false;
2105 }
2106 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002107}
2108
2109
lrn@chromium.org303ada72010-10-27 09:33:13 +00002110MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002111 if (!StringShape(this).IsCons()) return this;
2112 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002113 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002114 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002115}
2116
2117
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002118String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002119 MaybeObject* flat = TryFlatten(pretenure);
2120 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002121 if (!flat->ToObject(&successfully_flattened)) return this;
2122 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002123}
2124
2125
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002126uint16_t String::Get(int index) {
2127 ASSERT(index >= 0 && index < length());
2128 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002129 case kSeqStringTag | kAsciiStringTag:
2130 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2131 case kSeqStringTag | kTwoByteStringTag:
2132 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2133 case kConsStringTag | kAsciiStringTag:
2134 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002135 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002136 case kExternalStringTag | kAsciiStringTag:
2137 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2138 case kExternalStringTag | kTwoByteStringTag:
2139 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002140 case kSlicedStringTag | kAsciiStringTag:
2141 case kSlicedStringTag | kTwoByteStringTag:
2142 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002143 default:
2144 break;
2145 }
2146
2147 UNREACHABLE();
2148 return 0;
2149}
2150
2151
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002152void String::Set(int index, uint16_t value) {
2153 ASSERT(index >= 0 && index < length());
2154 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002155
ager@chromium.org5ec48922009-05-05 07:25:34 +00002156 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002157 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2158 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002159}
2160
2161
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002162bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002163 if (!StringShape(this).IsCons()) return true;
2164 return ConsString::cast(this)->second()->length() == 0;
2165}
2166
2167
2168String* String::GetUnderlying() {
2169 // Giving direct access to underlying string only makes sense if the
2170 // wrapping string is already flattened.
2171 ASSERT(this->IsFlat());
2172 ASSERT(StringShape(this).IsIndirect());
2173 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2174 const int kUnderlyingOffset = SlicedString::kParentOffset;
2175 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002176}
2177
2178
ager@chromium.org7c537e22008-10-16 08:43:32 +00002179uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002180 ASSERT(index >= 0 && index < length());
2181 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2182}
2183
2184
ager@chromium.org7c537e22008-10-16 08:43:32 +00002185void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002186 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2187 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2188 static_cast<byte>(value));
2189}
2190
2191
ager@chromium.org7c537e22008-10-16 08:43:32 +00002192Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002193 return FIELD_ADDR(this, kHeaderSize);
2194}
2195
2196
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002197char* SeqAsciiString::GetChars() {
2198 return reinterpret_cast<char*>(GetCharsAddress());
2199}
2200
2201
ager@chromium.org7c537e22008-10-16 08:43:32 +00002202Address SeqTwoByteString::GetCharsAddress() {
2203 return FIELD_ADDR(this, kHeaderSize);
2204}
2205
2206
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002207uc16* SeqTwoByteString::GetChars() {
2208 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2209}
2210
2211
ager@chromium.org7c537e22008-10-16 08:43:32 +00002212uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002213 ASSERT(index >= 0 && index < length());
2214 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2215}
2216
2217
ager@chromium.org7c537e22008-10-16 08:43:32 +00002218void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002219 ASSERT(index >= 0 && index < length());
2220 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2221}
2222
2223
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002224int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002225 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002226}
2227
2228
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002229int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002230 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002231}
2232
2233
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002234String* SlicedString::parent() {
2235 return String::cast(READ_FIELD(this, kParentOffset));
2236}
2237
2238
2239void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002240 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002241 WRITE_FIELD(this, kParentOffset, parent);
2242}
2243
2244
2245SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2246
2247
ager@chromium.org870a0b62008-11-04 11:43:05 +00002248String* ConsString::first() {
2249 return String::cast(READ_FIELD(this, kFirstOffset));
2250}
2251
2252
2253Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002254 return READ_FIELD(this, kFirstOffset);
2255}
2256
2257
ager@chromium.org870a0b62008-11-04 11:43:05 +00002258void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002259 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002260 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002261}
2262
2263
ager@chromium.org870a0b62008-11-04 11:43:05 +00002264String* ConsString::second() {
2265 return String::cast(READ_FIELD(this, kSecondOffset));
2266}
2267
2268
2269Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002270 return READ_FIELD(this, kSecondOffset);
2271}
2272
2273
ager@chromium.org870a0b62008-11-04 11:43:05 +00002274void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002275 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002276 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002277}
2278
2279
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002280const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002281 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2282}
2283
2284
2285void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002286 const ExternalAsciiString::Resource* resource) {
2287 *reinterpret_cast<const Resource**>(
2288 FIELD_ADDR(this, kResourceOffset)) = resource;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002289}
2290
2291
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002292const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002293 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2294}
2295
2296
2297void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002298 const ExternalTwoByteString::Resource* resource) {
2299 *reinterpret_cast<const Resource**>(
2300 FIELD_ADDR(this, kResourceOffset)) = resource;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002301}
2302
2303
ager@chromium.orgac091b72010-05-05 07:34:42 +00002304void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002305 set_finger_index(kEntriesIndex);
2306 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002307}
2308
2309
2310void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002311 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002312 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002313 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002314 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002315 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002316 MakeZeroSize();
2317}
2318
2319
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002320int JSFunctionResultCache::size() {
2321 return Smi::cast(get(kCacheSizeIndex))->value();
2322}
2323
2324
2325void JSFunctionResultCache::set_size(int size) {
2326 set(kCacheSizeIndex, Smi::FromInt(size));
2327}
2328
2329
2330int JSFunctionResultCache::finger_index() {
2331 return Smi::cast(get(kFingerIndex))->value();
2332}
2333
2334
2335void JSFunctionResultCache::set_finger_index(int finger_index) {
2336 set(kFingerIndex, Smi::FromInt(finger_index));
2337}
2338
2339
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002340byte ByteArray::get(int index) {
2341 ASSERT(index >= 0 && index < this->length());
2342 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2343}
2344
2345
2346void ByteArray::set(int index, byte value) {
2347 ASSERT(index >= 0 && index < this->length());
2348 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2349}
2350
2351
2352int ByteArray::get_int(int index) {
2353 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2354 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2355}
2356
2357
2358ByteArray* ByteArray::FromDataStartAddress(Address address) {
2359 ASSERT_TAG_ALIGNED(address);
2360 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2361}
2362
2363
2364Address ByteArray::GetDataStartAddress() {
2365 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2366}
2367
2368
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002369uint8_t* ExternalPixelArray::external_pixel_pointer() {
2370 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002371}
2372
2373
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002374uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002375 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002376 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002377 return ptr[index];
2378}
2379
2380
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002381MaybeObject* ExternalPixelArray::get(int index) {
2382 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2383}
2384
2385
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002386void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002387 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002388 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002389 ptr[index] = value;
2390}
2391
2392
ager@chromium.org3811b432009-10-28 14:53:37 +00002393void* ExternalArray::external_pointer() {
2394 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2395 return reinterpret_cast<void*>(ptr);
2396}
2397
2398
2399void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2400 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2401 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2402}
2403
2404
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002405int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002406 ASSERT((index >= 0) && (index < this->length()));
2407 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2408 return ptr[index];
2409}
2410
2411
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002412MaybeObject* ExternalByteArray::get(int index) {
2413 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2414}
2415
2416
ager@chromium.org3811b432009-10-28 14:53:37 +00002417void ExternalByteArray::set(int index, int8_t value) {
2418 ASSERT((index >= 0) && (index < this->length()));
2419 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2420 ptr[index] = value;
2421}
2422
2423
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002424uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002425 ASSERT((index >= 0) && (index < this->length()));
2426 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2427 return ptr[index];
2428}
2429
2430
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002431MaybeObject* ExternalUnsignedByteArray::get(int index) {
2432 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2433}
2434
2435
ager@chromium.org3811b432009-10-28 14:53:37 +00002436void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2437 ASSERT((index >= 0) && (index < this->length()));
2438 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2439 ptr[index] = value;
2440}
2441
2442
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002443int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002444 ASSERT((index >= 0) && (index < this->length()));
2445 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2446 return ptr[index];
2447}
2448
2449
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002450MaybeObject* ExternalShortArray::get(int index) {
2451 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2452}
2453
2454
ager@chromium.org3811b432009-10-28 14:53:37 +00002455void ExternalShortArray::set(int index, int16_t value) {
2456 ASSERT((index >= 0) && (index < this->length()));
2457 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2458 ptr[index] = value;
2459}
2460
2461
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002462uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002463 ASSERT((index >= 0) && (index < this->length()));
2464 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2465 return ptr[index];
2466}
2467
2468
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002469MaybeObject* ExternalUnsignedShortArray::get(int index) {
2470 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2471}
2472
2473
ager@chromium.org3811b432009-10-28 14:53:37 +00002474void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2475 ASSERT((index >= 0) && (index < this->length()));
2476 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2477 ptr[index] = value;
2478}
2479
2480
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002481int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002482 ASSERT((index >= 0) && (index < this->length()));
2483 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2484 return ptr[index];
2485}
2486
2487
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002488MaybeObject* ExternalIntArray::get(int index) {
2489 return GetHeap()->NumberFromInt32(get_scalar(index));
2490}
2491
2492
ager@chromium.org3811b432009-10-28 14:53:37 +00002493void ExternalIntArray::set(int index, int32_t value) {
2494 ASSERT((index >= 0) && (index < this->length()));
2495 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2496 ptr[index] = value;
2497}
2498
2499
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002500uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002501 ASSERT((index >= 0) && (index < this->length()));
2502 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2503 return ptr[index];
2504}
2505
2506
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002507MaybeObject* ExternalUnsignedIntArray::get(int index) {
2508 return GetHeap()->NumberFromUint32(get_scalar(index));
2509}
2510
2511
ager@chromium.org3811b432009-10-28 14:53:37 +00002512void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2513 ASSERT((index >= 0) && (index < this->length()));
2514 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2515 ptr[index] = value;
2516}
2517
2518
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002519float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002520 ASSERT((index >= 0) && (index < this->length()));
2521 float* ptr = static_cast<float*>(external_pointer());
2522 return ptr[index];
2523}
2524
2525
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002526MaybeObject* ExternalFloatArray::get(int index) {
2527 return GetHeap()->NumberFromDouble(get_scalar(index));
2528}
2529
2530
ager@chromium.org3811b432009-10-28 14:53:37 +00002531void ExternalFloatArray::set(int index, float value) {
2532 ASSERT((index >= 0) && (index < this->length()));
2533 float* ptr = static_cast<float*>(external_pointer());
2534 ptr[index] = value;
2535}
2536
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002537
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002538double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002539 ASSERT((index >= 0) && (index < this->length()));
2540 double* ptr = static_cast<double*>(external_pointer());
2541 return ptr[index];
2542}
2543
2544
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002545MaybeObject* ExternalDoubleArray::get(int index) {
2546 return GetHeap()->NumberFromDouble(get_scalar(index));
2547}
2548
2549
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002550void ExternalDoubleArray::set(int index, double value) {
2551 ASSERT((index >= 0) && (index < this->length()));
2552 double* ptr = static_cast<double*>(external_pointer());
2553 ptr[index] = value;
2554}
2555
2556
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002557int Map::visitor_id() {
2558 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2559}
2560
2561
2562void Map::set_visitor_id(int id) {
2563 ASSERT(0 <= id && id < 256);
2564 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2565}
2566
ager@chromium.org3811b432009-10-28 14:53:37 +00002567
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002568int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002569 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2570}
2571
2572
2573int Map::inobject_properties() {
2574 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002575}
2576
2577
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002578int Map::pre_allocated_property_fields() {
2579 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2580}
2581
2582
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002583int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002584 int instance_size = map->instance_size();
2585 if (instance_size != kVariableSizeSentinel) return instance_size;
2586 // We can ignore the "symbol" bit becase it is only set for symbols
2587 // and implies a string type.
2588 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002589 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002590 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002591 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002592 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002593 if (instance_type == ASCII_STRING_TYPE) {
2594 return SeqAsciiString::SizeFor(
2595 reinterpret_cast<SeqAsciiString*>(this)->length());
2596 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002597 if (instance_type == BYTE_ARRAY_TYPE) {
2598 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2599 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002600 if (instance_type == FREE_SPACE_TYPE) {
2601 return reinterpret_cast<FreeSpace*>(this)->size();
2602 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002603 if (instance_type == STRING_TYPE) {
2604 return SeqTwoByteString::SizeFor(
2605 reinterpret_cast<SeqTwoByteString*>(this)->length());
2606 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002607 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2608 return FixedDoubleArray::SizeFor(
2609 reinterpret_cast<FixedDoubleArray*>(this)->length());
2610 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002611 ASSERT(instance_type == CODE_TYPE);
2612 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002613}
2614
2615
2616void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002617 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002618 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002619 ASSERT(0 <= value && value < 256);
2620 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2621}
2622
2623
ager@chromium.org7c537e22008-10-16 08:43:32 +00002624void Map::set_inobject_properties(int value) {
2625 ASSERT(0 <= value && value < 256);
2626 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2627}
2628
2629
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002630void Map::set_pre_allocated_property_fields(int value) {
2631 ASSERT(0 <= value && value < 256);
2632 WRITE_BYTE_FIELD(this,
2633 kPreAllocatedPropertyFieldsOffset,
2634 static_cast<byte>(value));
2635}
2636
2637
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002638InstanceType Map::instance_type() {
2639 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2640}
2641
2642
2643void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002644 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2645}
2646
2647
2648int Map::unused_property_fields() {
2649 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2650}
2651
2652
2653void Map::set_unused_property_fields(int value) {
2654 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2655}
2656
2657
2658byte Map::bit_field() {
2659 return READ_BYTE_FIELD(this, kBitFieldOffset);
2660}
2661
2662
2663void Map::set_bit_field(byte value) {
2664 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2665}
2666
2667
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002668byte Map::bit_field2() {
2669 return READ_BYTE_FIELD(this, kBitField2Offset);
2670}
2671
2672
2673void Map::set_bit_field2(byte value) {
2674 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2675}
2676
2677
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002678void Map::set_non_instance_prototype(bool value) {
2679 if (value) {
2680 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2681 } else {
2682 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2683 }
2684}
2685
2686
2687bool Map::has_non_instance_prototype() {
2688 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2689}
2690
2691
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002692void Map::set_function_with_prototype(bool value) {
2693 if (value) {
2694 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2695 } else {
2696 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2697 }
2698}
2699
2700
2701bool Map::function_with_prototype() {
2702 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2703}
2704
2705
ager@chromium.org870a0b62008-11-04 11:43:05 +00002706void Map::set_is_access_check_needed(bool access_check_needed) {
2707 if (access_check_needed) {
2708 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2709 } else {
2710 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2711 }
2712}
2713
2714
2715bool Map::is_access_check_needed() {
2716 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2717}
2718
2719
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002720void Map::set_is_extensible(bool value) {
2721 if (value) {
2722 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2723 } else {
2724 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2725 }
2726}
2727
2728bool Map::is_extensible() {
2729 return ((1 << kIsExtensible) & bit_field2()) != 0;
2730}
2731
2732
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002733void Map::set_attached_to_shared_function_info(bool value) {
2734 if (value) {
2735 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2736 } else {
2737 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2738 }
2739}
2740
2741bool Map::attached_to_shared_function_info() {
2742 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2743}
2744
2745
2746void Map::set_is_shared(bool value) {
2747 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002748 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002749 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002750 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002751 }
2752}
2753
2754bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002755 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002756}
2757
2758
2759JSFunction* Map::unchecked_constructor() {
2760 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2761}
2762
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002763
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002764Code::Flags Code::flags() {
2765 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2766}
2767
2768
2769void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002770 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002771 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002772 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2773 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002774 ExtractArgumentsCountFromFlags(flags) >= 0);
2775 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2776}
2777
2778
2779Code::Kind Code::kind() {
2780 return ExtractKindFromFlags(flags());
2781}
2782
2783
kasper.lund7276f142008-07-30 08:49:36 +00002784InlineCacheState Code::ic_state() {
2785 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002786 // Only allow uninitialized or debugger states for non-IC code
2787 // objects. This is used in the debugger to determine whether or not
2788 // a call to code object has been replaced with a debug break call.
2789 ASSERT(is_inline_cache_stub() ||
2790 result == UNINITIALIZED ||
2791 result == DEBUG_BREAK ||
2792 result == DEBUG_PREPARE_STEP_IN);
2793 return result;
2794}
2795
2796
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002797Code::ExtraICState Code::extra_ic_state() {
2798 ASSERT(is_inline_cache_stub());
2799 return ExtractExtraICStateFromFlags(flags());
2800}
2801
2802
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002803PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002804 return ExtractTypeFromFlags(flags());
2805}
2806
2807
2808int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002809 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002810 return ExtractArgumentsCountFromFlags(flags());
2811}
2812
2813
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002814int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002815 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002816 kind() == UNARY_OP_IC ||
2817 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002818 kind() == COMPARE_IC ||
2819 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002820 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002821}
2822
2823
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002824void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002825 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002826 kind() == UNARY_OP_IC ||
2827 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002828 kind() == COMPARE_IC ||
2829 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002830 ASSERT(0 <= major && major < 256);
2831 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002832}
2833
2834
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002835bool Code::is_pregenerated() {
2836 return kind() == STUB && IsPregeneratedField::decode(flags());
2837}
2838
2839
2840void Code::set_is_pregenerated(bool value) {
2841 ASSERT(kind() == STUB);
2842 Flags f = flags();
2843 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
2844 set_flags(f);
2845}
2846
2847
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002848bool Code::optimizable() {
2849 ASSERT(kind() == FUNCTION);
2850 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2851}
2852
2853
2854void Code::set_optimizable(bool value) {
2855 ASSERT(kind() == FUNCTION);
2856 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2857}
2858
2859
2860bool Code::has_deoptimization_support() {
2861 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002862 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2863 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002864}
2865
2866
2867void Code::set_has_deoptimization_support(bool value) {
2868 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002869 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2870 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
2871 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
2872}
2873
2874
2875bool Code::has_debug_break_slots() {
2876 ASSERT(kind() == FUNCTION);
2877 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2878 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
2879}
2880
2881
2882void Code::set_has_debug_break_slots(bool value) {
2883 ASSERT(kind() == FUNCTION);
2884 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2885 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
2886 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002887}
2888
2889
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002890bool Code::is_compiled_optimizable() {
2891 ASSERT(kind() == FUNCTION);
2892 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2893 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
2894}
2895
2896
2897void Code::set_compiled_optimizable(bool value) {
2898 ASSERT(kind() == FUNCTION);
2899 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2900 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
2901 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
2902}
2903
2904
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002905int Code::allow_osr_at_loop_nesting_level() {
2906 ASSERT(kind() == FUNCTION);
2907 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2908}
2909
2910
2911void Code::set_allow_osr_at_loop_nesting_level(int level) {
2912 ASSERT(kind() == FUNCTION);
2913 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2914 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2915}
2916
2917
2918unsigned Code::stack_slots() {
2919 ASSERT(kind() == OPTIMIZED_FUNCTION);
2920 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2921}
2922
2923
2924void Code::set_stack_slots(unsigned slots) {
2925 ASSERT(kind() == OPTIMIZED_FUNCTION);
2926 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2927}
2928
2929
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002930unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002931 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002932 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002933}
2934
2935
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002936void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002937 ASSERT(kind() == OPTIMIZED_FUNCTION);
2938 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002939 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002940}
2941
2942
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002943unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002944 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002945 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002946}
2947
2948
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002949void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002950 ASSERT(kind() == FUNCTION);
2951 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002952 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002953}
2954
2955
2956CheckType Code::check_type() {
2957 ASSERT(is_call_stub() || is_keyed_call_stub());
2958 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2959 return static_cast<CheckType>(type);
2960}
2961
2962
2963void Code::set_check_type(CheckType value) {
2964 ASSERT(is_call_stub() || is_keyed_call_stub());
2965 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2966}
2967
2968
danno@chromium.org40cb8782011-05-25 07:58:50 +00002969byte Code::unary_op_type() {
2970 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002971 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
2972}
2973
2974
danno@chromium.org40cb8782011-05-25 07:58:50 +00002975void Code::set_unary_op_type(byte value) {
2976 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002977 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
2978}
2979
2980
danno@chromium.org40cb8782011-05-25 07:58:50 +00002981byte Code::binary_op_type() {
2982 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002983 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2984}
2985
2986
danno@chromium.org40cb8782011-05-25 07:58:50 +00002987void Code::set_binary_op_type(byte value) {
2988 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002989 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2990}
2991
2992
danno@chromium.org40cb8782011-05-25 07:58:50 +00002993byte Code::binary_op_result_type() {
2994 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002995 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2996}
2997
2998
danno@chromium.org40cb8782011-05-25 07:58:50 +00002999void Code::set_binary_op_result_type(byte value) {
3000 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003001 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3002}
3003
3004
3005byte Code::compare_state() {
3006 ASSERT(is_compare_ic_stub());
3007 return READ_BYTE_FIELD(this, kCompareStateOffset);
3008}
3009
3010
3011void Code::set_compare_state(byte value) {
3012 ASSERT(is_compare_ic_stub());
3013 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3014}
3015
3016
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003017byte Code::to_boolean_state() {
3018 ASSERT(is_to_boolean_ic_stub());
3019 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3020}
3021
3022
3023void Code::set_to_boolean_state(byte value) {
3024 ASSERT(is_to_boolean_ic_stub());
3025 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3026}
3027
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003028
3029bool Code::has_function_cache() {
3030 ASSERT(kind() == STUB);
3031 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3032}
3033
3034
3035void Code::set_has_function_cache(bool flag) {
3036 ASSERT(kind() == STUB);
3037 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3038}
3039
3040
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003041bool Code::is_inline_cache_stub() {
3042 Kind kind = this->kind();
3043 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3044}
3045
3046
3047Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003048 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003049 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003050 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003051 int argc,
3052 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003053 // Extra IC state is only allowed for call IC stubs or for store IC
3054 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003055 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003056 kind == CALL_IC ||
3057 kind == STORE_IC ||
3058 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003059 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003060 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003061 | ICStateField::encode(ic_state)
3062 | TypeField::encode(type)
3063 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003064 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003065 | CacheHolderField::encode(holder);
3066 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003067}
3068
3069
3070Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3071 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003072 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003073 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003074 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003075 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003076}
3077
3078
3079Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003080 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003081}
3082
3083
kasper.lund7276f142008-07-30 08:49:36 +00003084InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003085 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003086}
3087
3088
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003089Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003090 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003091}
3092
3093
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003094PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003095 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003096}
3097
3098
3099int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003100 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003101}
3102
3103
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003104InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003105 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003106}
3107
3108
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003109Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003110 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003111 return static_cast<Flags>(bits);
3112}
3113
3114
ager@chromium.org8bb60582008-12-11 12:02:20 +00003115Code* Code::GetCodeFromTargetAddress(Address address) {
3116 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3117 // GetCodeFromTargetAddress might be called when marking objects during mark
3118 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3119 // Code::cast. Code::cast does not work when the object's map is
3120 // marked.
3121 Code* result = reinterpret_cast<Code*>(code);
3122 return result;
3123}
3124
3125
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003126Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3127 return HeapObject::
3128 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3129}
3130
3131
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003132Object* Map::prototype() {
3133 return READ_FIELD(this, kPrototypeOffset);
3134}
3135
3136
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003137void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003138 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003139 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003140 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003141}
3142
3143
danno@chromium.org40cb8782011-05-25 07:58:50 +00003144DescriptorArray* Map::instance_descriptors() {
3145 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3146 if (object->IsSmi()) {
3147 return HEAP->empty_descriptor_array();
3148 } else {
3149 return DescriptorArray::cast(object);
3150 }
3151}
3152
3153
3154void Map::init_instance_descriptors() {
3155 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3156}
3157
3158
3159void Map::clear_instance_descriptors() {
3160 Object* object = READ_FIELD(this,
3161 kInstanceDescriptorsOrBitField3Offset);
3162 if (!object->IsSmi()) {
3163 WRITE_FIELD(
3164 this,
3165 kInstanceDescriptorsOrBitField3Offset,
3166 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3167 }
3168}
3169
3170
3171void Map::set_instance_descriptors(DescriptorArray* value,
3172 WriteBarrierMode mode) {
3173 Object* object = READ_FIELD(this,
3174 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003175 Heap* heap = GetHeap();
3176 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003177 clear_instance_descriptors();
3178 return;
3179 } else {
3180 if (object->IsSmi()) {
3181 value->set_bit_field3_storage(Smi::cast(object)->value());
3182 } else {
3183 value->set_bit_field3_storage(
3184 DescriptorArray::cast(object)->bit_field3_storage());
3185 }
3186 }
3187 ASSERT(!is_shared());
3188 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003189 CONDITIONAL_WRITE_BARRIER(
3190 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003191}
3192
3193
3194int Map::bit_field3() {
3195 Object* object = READ_FIELD(this,
3196 kInstanceDescriptorsOrBitField3Offset);
3197 if (object->IsSmi()) {
3198 return Smi::cast(object)->value();
3199 } else {
3200 return DescriptorArray::cast(object)->bit_field3_storage();
3201 }
3202}
3203
3204
3205void Map::set_bit_field3(int value) {
3206 ASSERT(Smi::IsValid(value));
3207 Object* object = READ_FIELD(this,
3208 kInstanceDescriptorsOrBitField3Offset);
3209 if (object->IsSmi()) {
3210 WRITE_FIELD(this,
3211 kInstanceDescriptorsOrBitField3Offset,
3212 Smi::FromInt(value));
3213 } else {
3214 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3215 }
3216}
3217
3218
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003219FixedArray* Map::unchecked_prototype_transitions() {
3220 return reinterpret_cast<FixedArray*>(
3221 READ_FIELD(this, kPrototypeTransitionsOffset));
3222}
3223
3224
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003225ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003226ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003227ACCESSORS(Map, constructor, Object, kConstructorOffset)
3228
3229ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003230ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003231ACCESSORS(JSFunction,
3232 next_function_link,
3233 Object,
3234 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003235
3236ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3237ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003238ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003239
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003240ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003241
3242ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3243ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3244ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3245ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3246ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3247
3248ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3249ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3250ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3251
3252ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3253ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3254ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3255ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3256ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3257ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3258
3259ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3260ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3261
3262ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3263ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3264
3265ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3266ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003267ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3268 kPropertyAccessorsOffset)
3269ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3270 kPrototypeTemplateOffset)
3271ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3272ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3273 kNamedPropertyHandlerOffset)
3274ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3275 kIndexedPropertyHandlerOffset)
3276ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3277 kInstanceTemplateOffset)
3278ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3279ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003280ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3281 kInstanceCallHandlerOffset)
3282ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3283 kAccessCheckInfoOffset)
3284ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3285
3286ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003287ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3288 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003289
3290ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3291ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3292
3293ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3294
3295ACCESSORS(Script, source, Object, kSourceOffset)
3296ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003297ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003298ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3299ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003300ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003301ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003302ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003303ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003304ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003305ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003306ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003307ACCESSORS(Script, eval_from_instructions_offset, Smi,
3308 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003309
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003310#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003311ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3312ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3313ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3314ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3315
3316ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3317ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3318ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3319ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003320#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003321
3322ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003323ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3324ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003325ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3326 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003327ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003328ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3329ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003330ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003331ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3332 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003333
3334BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3335 kHiddenPrototypeBit)
3336BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3337BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3338 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003339BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3340 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003341BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3342 kIsExpressionBit)
3343BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3344 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003345BOOL_GETTER(SharedFunctionInfo,
3346 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003347 has_only_simple_this_property_assignments,
3348 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003349BOOL_ACCESSORS(SharedFunctionInfo,
3350 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003351 allows_lazy_compilation,
3352 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003353BOOL_ACCESSORS(SharedFunctionInfo,
3354 compiler_hints,
3355 uses_arguments,
3356 kUsesArguments)
3357BOOL_ACCESSORS(SharedFunctionInfo,
3358 compiler_hints,
3359 has_duplicate_parameters,
3360 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003361
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003362
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003363#if V8_HOST_ARCH_32_BIT
3364SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3365SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003366 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003367SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003368 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003369SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3370SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003371 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003372SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3373SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003374 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003375SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003376 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003377SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003378 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003379SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003380#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003381
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003382#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003383 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003384 int holder::name() { \
3385 int value = READ_INT_FIELD(this, offset); \
3386 ASSERT(kHeapObjectTag == 1); \
3387 ASSERT((value & kHeapObjectTag) == 0); \
3388 return value >> 1; \
3389 } \
3390 void holder::set_##name(int value) { \
3391 ASSERT(kHeapObjectTag == 1); \
3392 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3393 (value & 0xC0000000) == 0x000000000); \
3394 WRITE_INT_FIELD(this, \
3395 offset, \
3396 (value << 1) & ~kHeapObjectTag); \
3397 }
3398
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003399#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3400 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003401 INT_ACCESSORS(holder, name, offset)
3402
3403
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003404PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003405PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3406 formal_parameter_count,
3407 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003408
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003409PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3410 expected_nof_properties,
3411 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003412PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3413
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003414PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3415PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3416 start_position_and_type,
3417 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003418
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003419PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3420 function_token_position,
3421 kFunctionTokenPositionOffset)
3422PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3423 compiler_hints,
3424 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003425
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003426PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3427 this_property_assignments_count,
3428 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003429PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003430#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003431
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003432
3433int SharedFunctionInfo::construction_count() {
3434 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3435}
3436
3437
3438void SharedFunctionInfo::set_construction_count(int value) {
3439 ASSERT(0 <= value && value < 256);
3440 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3441}
3442
3443
whesse@chromium.org7b260152011-06-20 15:33:18 +00003444BOOL_ACCESSORS(SharedFunctionInfo,
3445 compiler_hints,
3446 live_objects_may_exist,
3447 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003448
3449
3450bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003451 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003452}
3453
3454
whesse@chromium.org7b260152011-06-20 15:33:18 +00003455BOOL_GETTER(SharedFunctionInfo,
3456 compiler_hints,
3457 optimization_disabled,
3458 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003459
3460
3461void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3462 set_compiler_hints(BooleanBit::set(compiler_hints(),
3463 kOptimizationDisabled,
3464 disable));
3465 // If disabling optimizations we reflect that in the code object so
3466 // it will not be counted as optimizable code.
3467 if ((code()->kind() == Code::FUNCTION) && disable) {
3468 code()->set_optimizable(false);
3469 }
3470}
3471
3472
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003473StrictModeFlag SharedFunctionInfo::strict_mode_flag() {
3474 return BooleanBit::get(compiler_hints(), kStrictModeFunction)
3475 ? kStrictMode : kNonStrictMode;
3476}
3477
3478
3479void SharedFunctionInfo::set_strict_mode_flag(StrictModeFlag strict_mode_flag) {
3480 ASSERT(strict_mode_flag == kStrictMode ||
3481 strict_mode_flag == kNonStrictMode);
3482 bool value = strict_mode_flag == kStrictMode;
3483 set_compiler_hints(
3484 BooleanBit::set(compiler_hints(), kStrictModeFunction, value));
3485}
3486
3487
3488BOOL_GETTER(SharedFunctionInfo, compiler_hints, strict_mode,
3489 kStrictModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003490BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3491BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3492 name_should_print_as_anonymous,
3493 kNameShouldPrintAsAnonymous)
3494BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3495BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003496
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003497ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3498ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3499
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003500ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3501
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003502bool Script::HasValidSource() {
3503 Object* src = this->source();
3504 if (!src->IsString()) return true;
3505 String* src_str = String::cast(src);
3506 if (!StringShape(src_str).IsExternal()) return true;
3507 if (src_str->IsAsciiRepresentation()) {
3508 return ExternalAsciiString::cast(src)->resource() != NULL;
3509 } else if (src_str->IsTwoByteRepresentation()) {
3510 return ExternalTwoByteString::cast(src)->resource() != NULL;
3511 }
3512 return true;
3513}
3514
3515
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003516void SharedFunctionInfo::DontAdaptArguments() {
3517 ASSERT(code()->kind() == Code::BUILTIN);
3518 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3519}
3520
3521
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003522int SharedFunctionInfo::start_position() {
3523 return start_position_and_type() >> kStartPositionShift;
3524}
3525
3526
3527void SharedFunctionInfo::set_start_position(int start_position) {
3528 set_start_position_and_type((start_position << kStartPositionShift)
3529 | (start_position_and_type() & ~kStartPositionMask));
3530}
3531
3532
3533Code* SharedFunctionInfo::code() {
3534 return Code::cast(READ_FIELD(this, kCodeOffset));
3535}
3536
3537
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003538Code* SharedFunctionInfo::unchecked_code() {
3539 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3540}
3541
3542
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003543void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003544 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003545 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003546}
3547
3548
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003549ScopeInfo* SharedFunctionInfo::scope_info() {
3550 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003551}
3552
3553
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003554void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003555 WriteBarrierMode mode) {
3556 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003557 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3558 this,
3559 kScopeInfoOffset,
3560 reinterpret_cast<Object*>(value),
3561 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003562}
3563
3564
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003565Smi* SharedFunctionInfo::deopt_counter() {
3566 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3567}
3568
3569
3570void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3571 WRITE_FIELD(this, kDeoptCounterOffset, value);
3572}
3573
3574
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003575bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003576 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003577 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003578}
3579
3580
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003581bool SharedFunctionInfo::IsApiFunction() {
3582 return function_data()->IsFunctionTemplateInfo();
3583}
3584
3585
3586FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3587 ASSERT(IsApiFunction());
3588 return FunctionTemplateInfo::cast(function_data());
3589}
3590
3591
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003592bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003593 return function_data()->IsSmi();
3594}
3595
3596
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003597BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3598 ASSERT(HasBuiltinFunctionId());
3599 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003600}
3601
3602
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003603int SharedFunctionInfo::code_age() {
3604 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3605}
3606
3607
3608void SharedFunctionInfo::set_code_age(int code_age) {
3609 set_compiler_hints(compiler_hints() |
3610 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3611}
3612
3613
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003614bool SharedFunctionInfo::has_deoptimization_support() {
3615 Code* code = this->code();
3616 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3617}
3618
3619
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003620bool JSFunction::IsBuiltin() {
3621 return context()->global()->IsJSBuiltinsObject();
3622}
3623
3624
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003625bool JSFunction::NeedsArgumentsAdaption() {
3626 return shared()->formal_parameter_count() !=
3627 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3628}
3629
3630
3631bool JSFunction::IsOptimized() {
3632 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3633}
3634
3635
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003636bool JSFunction::IsOptimizable() {
3637 return code()->kind() == Code::FUNCTION && code()->optimizable();
3638}
3639
3640
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003641bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003642 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003643}
3644
3645
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003646Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003647 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003648}
3649
3650
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003651Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003652 return reinterpret_cast<Code*>(
3653 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003654}
3655
3656
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003657void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003658 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003659 Address entry = value->entry();
3660 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003661 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3662 this,
3663 HeapObject::RawField(this, kCodeEntryOffset),
3664 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003665}
3666
3667
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003668void JSFunction::ReplaceCode(Code* code) {
3669 bool was_optimized = IsOptimized();
3670 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3671
3672 set_code(code);
3673
3674 // Add/remove the function from the list of optimized functions for this
3675 // context based on the state change.
3676 if (!was_optimized && is_optimized) {
3677 context()->global_context()->AddOptimizedFunction(this);
3678 }
3679 if (was_optimized && !is_optimized) {
3680 context()->global_context()->RemoveOptimizedFunction(this);
3681 }
3682}
3683
3684
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003685Context* JSFunction::context() {
3686 return Context::cast(READ_FIELD(this, kContextOffset));
3687}
3688
3689
3690Object* JSFunction::unchecked_context() {
3691 return READ_FIELD(this, kContextOffset);
3692}
3693
3694
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003695SharedFunctionInfo* JSFunction::unchecked_shared() {
3696 return reinterpret_cast<SharedFunctionInfo*>(
3697 READ_FIELD(this, kSharedFunctionInfoOffset));
3698}
3699
3700
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003701void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003702 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003703 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003704 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003705}
3706
3707ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3708 kPrototypeOrInitialMapOffset)
3709
3710
3711Map* JSFunction::initial_map() {
3712 return Map::cast(prototype_or_initial_map());
3713}
3714
3715
3716void JSFunction::set_initial_map(Map* value) {
3717 set_prototype_or_initial_map(value);
3718}
3719
3720
3721bool JSFunction::has_initial_map() {
3722 return prototype_or_initial_map()->IsMap();
3723}
3724
3725
3726bool JSFunction::has_instance_prototype() {
3727 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3728}
3729
3730
3731bool JSFunction::has_prototype() {
3732 return map()->has_non_instance_prototype() || has_instance_prototype();
3733}
3734
3735
3736Object* JSFunction::instance_prototype() {
3737 ASSERT(has_instance_prototype());
3738 if (has_initial_map()) return initial_map()->prototype();
3739 // When there is no initial map and the prototype is a JSObject, the
3740 // initial map field is used for the prototype field.
3741 return prototype_or_initial_map();
3742}
3743
3744
3745Object* JSFunction::prototype() {
3746 ASSERT(has_prototype());
3747 // If the function's prototype property has been set to a non-JSObject
3748 // value, that value is stored in the constructor field of the map.
3749 if (map()->has_non_instance_prototype()) return map()->constructor();
3750 return instance_prototype();
3751}
3752
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003753bool JSFunction::should_have_prototype() {
3754 return map()->function_with_prototype();
3755}
3756
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003757
3758bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003759 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003760}
3761
3762
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003763FixedArray* JSFunction::literals() {
3764 ASSERT(!shared()->bound());
3765 return literals_or_bindings();
3766}
3767
3768
3769void JSFunction::set_literals(FixedArray* literals) {
3770 ASSERT(!shared()->bound());
3771 set_literals_or_bindings(literals);
3772}
3773
3774
3775FixedArray* JSFunction::function_bindings() {
3776 ASSERT(shared()->bound());
3777 return literals_or_bindings();
3778}
3779
3780
3781void JSFunction::set_function_bindings(FixedArray* bindings) {
3782 ASSERT(shared()->bound());
3783 // Bound function literal may be initialized to the empty fixed array
3784 // before the bindings are set.
3785 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
3786 bindings->map() == GetHeap()->fixed_cow_array_map());
3787 set_literals_or_bindings(bindings);
3788}
3789
3790
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003791int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003792 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003793 return literals()->length();
3794}
3795
3796
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003797Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003798 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003799 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003800}
3801
3802
3803void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3804 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003805 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003806 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003807 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003808}
3809
3810
3811Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003812 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003813 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3814}
3815
3816
3817void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3818 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003819 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003820 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003821 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003822}
3823
3824
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003825ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003826ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003827ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
3828ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
3829
3830
3831void JSProxy::InitializeBody(int object_size, Object* value) {
3832 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
3833 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
3834 WRITE_FIELD(this, offset, value);
3835 }
3836}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003837
3838
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003839ACCESSORS(JSSet, table, Object, kTableOffset)
3840ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003841ACCESSORS(JSWeakMap, table, Object, kTableOffset)
3842ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003843
3844
3845ObjectHashTable* JSWeakMap::unchecked_table() {
3846 return reinterpret_cast<ObjectHashTable*>(READ_FIELD(this, kTableOffset));
3847}
3848
3849
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003850Address Foreign::foreign_address() {
3851 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003852}
3853
3854
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003855void Foreign::set_foreign_address(Address value) {
3856 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003857}
3858
3859
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003860ACCESSORS(JSValue, value, Object, kValueOffset)
3861
3862
3863JSValue* JSValue::cast(Object* obj) {
3864 ASSERT(obj->IsJSValue());
3865 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3866 return reinterpret_cast<JSValue*>(obj);
3867}
3868
3869
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003870ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3871ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3872ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3873ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3874ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3875SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3876SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3877
3878
3879JSMessageObject* JSMessageObject::cast(Object* obj) {
3880 ASSERT(obj->IsJSMessageObject());
3881 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3882 return reinterpret_cast<JSMessageObject*>(obj);
3883}
3884
3885
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003886INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003887ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003888ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003889ACCESSORS(Code, next_code_flushing_candidate,
3890 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003891
3892
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003893byte* Code::instruction_start() {
3894 return FIELD_ADDR(this, kHeaderSize);
3895}
3896
3897
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003898byte* Code::instruction_end() {
3899 return instruction_start() + instruction_size();
3900}
3901
3902
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003903int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003904 return RoundUp(instruction_size(), kObjectAlignment);
3905}
3906
3907
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003908FixedArray* Code::unchecked_deoptimization_data() {
3909 return reinterpret_cast<FixedArray*>(
3910 READ_FIELD(this, kDeoptimizationDataOffset));
3911}
3912
3913
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003914ByteArray* Code::unchecked_relocation_info() {
3915 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003916}
3917
3918
3919byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003920 return unchecked_relocation_info()->GetDataStartAddress();
3921}
3922
3923
3924int Code::relocation_size() {
3925 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003926}
3927
3928
3929byte* Code::entry() {
3930 return instruction_start();
3931}
3932
3933
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003934bool Code::contains(byte* inner_pointer) {
3935 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003936}
3937
3938
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003939ACCESSORS(JSArray, length, Object, kLengthOffset)
3940
3941
ager@chromium.org236ad962008-09-25 09:45:57 +00003942ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003943
3944
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003945JSRegExp::Type JSRegExp::TypeTag() {
3946 Object* data = this->data();
3947 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3948 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3949 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003950}
3951
3952
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003953JSRegExp::Type JSRegExp::TypeTagUnchecked() {
3954 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
3955 return static_cast<JSRegExp::Type>(smi->value());
3956}
3957
3958
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003959int JSRegExp::CaptureCount() {
3960 switch (TypeTag()) {
3961 case ATOM:
3962 return 0;
3963 case IRREGEXP:
3964 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3965 default:
3966 UNREACHABLE();
3967 return -1;
3968 }
3969}
3970
3971
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003972JSRegExp::Flags JSRegExp::GetFlags() {
3973 ASSERT(this->data()->IsFixedArray());
3974 Object* data = this->data();
3975 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3976 return Flags(smi->value());
3977}
3978
3979
3980String* JSRegExp::Pattern() {
3981 ASSERT(this->data()->IsFixedArray());
3982 Object* data = this->data();
3983 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3984 return pattern;
3985}
3986
3987
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003988Object* JSRegExp::DataAt(int index) {
3989 ASSERT(TypeTag() != NOT_COMPILED);
3990 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003991}
3992
3993
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003994Object* JSRegExp::DataAtUnchecked(int index) {
3995 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
3996 int offset = FixedArray::kHeaderSize + index * kPointerSize;
3997 return READ_FIELD(fa, offset);
3998}
3999
4000
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004001void JSRegExp::SetDataAt(int index, Object* value) {
4002 ASSERT(TypeTag() != NOT_COMPILED);
4003 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4004 FixedArray::cast(data())->set(index, value);
4005}
4006
4007
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004008void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4009 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4010 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4011 if (value->IsSmi()) {
4012 fa->set_unchecked(index, Smi::cast(value));
4013 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004014 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004015 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4016 }
4017}
4018
4019
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004020ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004021 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004022#if DEBUG
4023 FixedArrayBase* fixed_array =
4024 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4025 Map* map = fixed_array->map();
4026 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004027 (map == GetHeap()->fixed_array_map() ||
4028 map == GetHeap()->fixed_cow_array_map())) ||
4029 (kind == FAST_DOUBLE_ELEMENTS &&
4030 fixed_array->IsFixedDoubleArray()) ||
4031 (kind == DICTIONARY_ELEMENTS &&
4032 fixed_array->IsFixedArray() &&
4033 fixed_array->IsDictionary()) ||
4034 (kind > DICTIONARY_ELEMENTS));
4035 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4036 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004037#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004038 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004039}
4040
4041
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004042ElementsAccessor* JSObject::GetElementsAccessor() {
4043 return ElementsAccessor::ForKind(GetElementsKind());
4044}
4045
4046
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004047bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004048 return GetElementsKind() == FAST_ELEMENTS;
4049}
4050
4051
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004052bool JSObject::HasFastSmiOnlyElements() {
4053 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4054}
4055
4056
4057bool JSObject::HasFastTypeElements() {
4058 ElementsKind elements_kind = GetElementsKind();
4059 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4060 elements_kind == FAST_ELEMENTS;
4061}
4062
4063
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004064bool JSObject::HasFastDoubleElements() {
4065 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4066}
4067
4068
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004069bool JSObject::HasDictionaryElements() {
4070 return GetElementsKind() == DICTIONARY_ELEMENTS;
4071}
4072
4073
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004074bool JSObject::HasNonStrictArgumentsElements() {
4075 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4076}
4077
4078
ager@chromium.org3811b432009-10-28 14:53:37 +00004079bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004080 HeapObject* array = elements();
4081 ASSERT(array != NULL);
4082 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004083}
4084
4085
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004086#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4087bool JSObject::HasExternal##name##Elements() { \
4088 HeapObject* array = elements(); \
4089 ASSERT(array != NULL); \
4090 if (!array->IsHeapObject()) \
4091 return false; \
4092 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004093}
4094
4095
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004096EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4097EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4098EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4099EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4100 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4101EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4102EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4103 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4104EXTERNAL_ELEMENTS_CHECK(Float,
4105 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004106EXTERNAL_ELEMENTS_CHECK(Double,
4107 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004108EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004109
4110
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004111bool JSObject::HasNamedInterceptor() {
4112 return map()->has_named_interceptor();
4113}
4114
4115
4116bool JSObject::HasIndexedInterceptor() {
4117 return map()->has_indexed_interceptor();
4118}
4119
4120
ager@chromium.org5c838252010-02-19 08:53:10 +00004121bool JSObject::AllowsSetElementsLength() {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004122 bool result = elements()->IsFixedArray() ||
4123 elements()->IsFixedDoubleArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004124 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00004125 return result;
4126}
4127
4128
lrn@chromium.org303ada72010-10-27 09:33:13 +00004129MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004130 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004131 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004132 Isolate* isolate = GetIsolate();
4133 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004134 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004135 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4136 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004137 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4138 return maybe_writable_elems;
4139 }
4140 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004141 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004142 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004143 return writable_elems;
4144}
4145
4146
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004147StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004148 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004149 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004150}
4151
4152
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004153NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004154 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004155 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004156}
4157
4158
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004159bool String::IsHashFieldComputed(uint32_t field) {
4160 return (field & kHashNotComputedMask) == 0;
4161}
4162
4163
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004164bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004165 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004166}
4167
4168
4169uint32_t String::Hash() {
4170 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004171 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004172 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004173 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004174 return ComputeAndSetHash();
4175}
4176
4177
ager@chromium.org7c537e22008-10-16 08:43:32 +00004178StringHasher::StringHasher(int length)
4179 : length_(length),
4180 raw_running_hash_(0),
4181 array_index_(0),
4182 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4183 is_first_char_(true),
4184 is_valid_(true) { }
4185
4186
4187bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004188 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004189}
4190
4191
4192void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004193 // Use the Jenkins one-at-a-time hash function to update the hash
4194 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004195 raw_running_hash_ += c;
4196 raw_running_hash_ += (raw_running_hash_ << 10);
4197 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004198 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004199 if (is_array_index_) {
4200 if (c < '0' || c > '9') {
4201 is_array_index_ = false;
4202 } else {
4203 int d = c - '0';
4204 if (is_first_char_) {
4205 is_first_char_ = false;
4206 if (c == '0' && length_ > 1) {
4207 is_array_index_ = false;
4208 return;
4209 }
4210 }
4211 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4212 is_array_index_ = false;
4213 } else {
4214 array_index_ = array_index_ * 10 + d;
4215 }
4216 }
4217 }
4218}
4219
4220
4221void StringHasher::AddCharacterNoIndex(uc32 c) {
4222 ASSERT(!is_array_index());
4223 raw_running_hash_ += c;
4224 raw_running_hash_ += (raw_running_hash_ << 10);
4225 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4226}
4227
4228
4229uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004230 // Get the calculated raw hash value and do some more bit ops to distribute
4231 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004232 uint32_t result = raw_running_hash_;
4233 result += (result << 3);
4234 result ^= (result >> 11);
4235 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004236 if (result == 0) {
4237 result = 27;
4238 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004239 return result;
4240}
4241
4242
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004243template <typename schar>
4244uint32_t HashSequentialString(const schar* chars, int length) {
4245 StringHasher hasher(length);
4246 if (!hasher.has_trivial_hash()) {
4247 int i;
4248 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4249 hasher.AddCharacter(chars[i]);
4250 }
4251 for (; i < length; i++) {
4252 hasher.AddCharacterNoIndex(chars[i]);
4253 }
4254 }
4255 return hasher.GetHashField();
4256}
4257
4258
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004259bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004260 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004261 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4262 return false;
4263 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004264 return SlowAsArrayIndex(index);
4265}
4266
4267
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004268Object* JSReceiver::GetPrototype() {
4269 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004270}
4271
4272
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004273bool JSReceiver::HasProperty(String* name) {
4274 if (IsJSProxy()) {
4275 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4276 }
4277 return GetPropertyAttribute(name) != ABSENT;
4278}
4279
4280
4281bool JSReceiver::HasLocalProperty(String* name) {
4282 if (IsJSProxy()) {
4283 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4284 }
4285 return GetLocalPropertyAttribute(name) != ABSENT;
4286}
4287
4288
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004289PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004290 return GetPropertyAttributeWithReceiver(this, key);
4291}
4292
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004293// TODO(504): this may be useful in other places too where JSGlobalProxy
4294// is used.
4295Object* JSObject::BypassGlobalProxy() {
4296 if (IsJSGlobalProxy()) {
4297 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004298 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004299 ASSERT(proto->IsJSGlobalObject());
4300 return proto;
4301 }
4302 return this;
4303}
4304
4305
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004306MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4307 return IsJSProxy()
4308 ? JSProxy::cast(this)->GetIdentityHash(flag)
4309 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004310}
4311
4312
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004313bool JSReceiver::HasElement(uint32_t index) {
4314 if (IsJSProxy()) {
4315 return JSProxy::cast(this)->HasElementWithHandler(index);
4316 }
4317 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004318}
4319
4320
4321bool AccessorInfo::all_can_read() {
4322 return BooleanBit::get(flag(), kAllCanReadBit);
4323}
4324
4325
4326void AccessorInfo::set_all_can_read(bool value) {
4327 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4328}
4329
4330
4331bool AccessorInfo::all_can_write() {
4332 return BooleanBit::get(flag(), kAllCanWriteBit);
4333}
4334
4335
4336void AccessorInfo::set_all_can_write(bool value) {
4337 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4338}
4339
4340
ager@chromium.org870a0b62008-11-04 11:43:05 +00004341bool AccessorInfo::prohibits_overwriting() {
4342 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4343}
4344
4345
4346void AccessorInfo::set_prohibits_overwriting(bool value) {
4347 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4348}
4349
4350
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004351PropertyAttributes AccessorInfo::property_attributes() {
4352 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4353}
4354
4355
4356void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004357 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004358}
4359
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004360
4361template<typename Shape, typename Key>
4362void Dictionary<Shape, Key>::SetEntry(int entry,
4363 Object* key,
4364 Object* value) {
4365 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4366}
4367
4368
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004369template<typename Shape, typename Key>
4370void Dictionary<Shape, Key>::SetEntry(int entry,
4371 Object* key,
4372 Object* value,
4373 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004374 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004375 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004376 AssertNoAllocation no_gc;
4377 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004378 FixedArray::set(index, key, mode);
4379 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004380 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004381}
4382
4383
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004384bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4385 ASSERT(other->IsNumber());
4386 return key == static_cast<uint32_t>(other->Number());
4387}
4388
4389
4390uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4391 return ComputeIntegerHash(key);
4392}
4393
4394
4395uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4396 ASSERT(other->IsNumber());
4397 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4398}
4399
4400
4401MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4402 return Isolate::Current()->heap()->NumberFromUint32(key);
4403}
4404
4405
4406bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4407 // We know that all entries in a hash table had their hash keys created.
4408 // Use that knowledge to have fast failure.
4409 if (key->Hash() != String::cast(other)->Hash()) return false;
4410 return key->Equals(String::cast(other));
4411}
4412
4413
4414uint32_t StringDictionaryShape::Hash(String* key) {
4415 return key->Hash();
4416}
4417
4418
4419uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4420 return String::cast(other)->Hash();
4421}
4422
4423
4424MaybeObject* StringDictionaryShape::AsObject(String* key) {
4425 return key;
4426}
4427
4428
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004429template <int entrysize>
4430bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4431 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004432}
4433
4434
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004435template <int entrysize>
4436uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004437 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4438 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004439}
4440
4441
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004442template <int entrysize>
4443uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4444 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004445 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4446 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004447}
4448
4449
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004450template <int entrysize>
4451MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004452 return key;
4453}
4454
4455
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004456void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004457 // No write barrier is needed since empty_fixed_array is not in new space.
4458 // Please note this function is used during marking:
4459 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004460 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4461 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004462}
4463
4464
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004465void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004466 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004467 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004468 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4469 if (elts->length() < required_size) {
4470 // Doubling in size would be overkill, but leave some slack to avoid
4471 // constantly growing.
4472 Expand(required_size + (required_size >> 3));
4473 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004474 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004475 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4476 // Expand will allocate a new backing store in new space even if the size
4477 // we asked for isn't larger than what we had before.
4478 Expand(required_size);
4479 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004480}
4481
4482
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004483void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004484 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004485 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4486}
4487
4488
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004489MaybeObject* JSArray::SetContent(FixedArray* storage) {
4490 MaybeObject* maybe_object = EnsureCanContainElements(storage);
4491 if (maybe_object->IsFailure()) return maybe_object;
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004492 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004493 set_elements(storage);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004494 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004495}
4496
4497
lrn@chromium.org303ada72010-10-27 09:33:13 +00004498MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004499 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004500 return GetHeap()->CopyFixedArray(this);
4501}
4502
4503
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004504MaybeObject* FixedDoubleArray::Copy() {
4505 if (length() == 0) return this;
4506 return GetHeap()->CopyFixedDoubleArray(this);
4507}
4508
4509
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004510Relocatable::Relocatable(Isolate* isolate) {
4511 ASSERT(isolate == Isolate::Current());
4512 isolate_ = isolate;
4513 prev_ = isolate->relocatable_top();
4514 isolate->set_relocatable_top(this);
4515}
4516
4517
4518Relocatable::~Relocatable() {
4519 ASSERT(isolate_ == Isolate::Current());
4520 ASSERT_EQ(isolate_->relocatable_top(), this);
4521 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004522}
4523
4524
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004525int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4526 return map->instance_size();
4527}
4528
4529
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004530void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004531 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004532 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004533}
4534
4535
4536template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004537void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004538 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004539 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004540}
4541
4542
4543void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4544 typedef v8::String::ExternalAsciiStringResource Resource;
4545 v->VisitExternalAsciiString(
4546 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4547}
4548
4549
4550template<typename StaticVisitor>
4551void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4552 typedef v8::String::ExternalAsciiStringResource Resource;
4553 StaticVisitor::VisitExternalAsciiString(
4554 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4555}
4556
4557
4558void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4559 typedef v8::String::ExternalStringResource Resource;
4560 v->VisitExternalTwoByteString(
4561 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4562}
4563
4564
4565template<typename StaticVisitor>
4566void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4567 typedef v8::String::ExternalStringResource Resource;
4568 StaticVisitor::VisitExternalTwoByteString(
4569 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4570}
4571
4572#define SLOT_ADDR(obj, offset) \
4573 reinterpret_cast<Object**>((obj)->address() + offset)
4574
4575template<int start_offset, int end_offset, int size>
4576void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4577 HeapObject* obj,
4578 ObjectVisitor* v) {
4579 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4580}
4581
4582
4583template<int start_offset>
4584void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4585 int object_size,
4586 ObjectVisitor* v) {
4587 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4588}
4589
4590#undef SLOT_ADDR
4591
4592
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004593#undef CAST_ACCESSOR
4594#undef INT_ACCESSORS
4595#undef SMI_ACCESSORS
4596#undef ACCESSORS
4597#undef FIELD_ADDR
4598#undef READ_FIELD
4599#undef WRITE_FIELD
4600#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004601#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004602#undef READ_MEMADDR_FIELD
4603#undef WRITE_MEMADDR_FIELD
4604#undef READ_DOUBLE_FIELD
4605#undef WRITE_DOUBLE_FIELD
4606#undef READ_INT_FIELD
4607#undef WRITE_INT_FIELD
4608#undef READ_SHORT_FIELD
4609#undef WRITE_SHORT_FIELD
4610#undef READ_BYTE_FIELD
4611#undef WRITE_BYTE_FIELD
4612
4613
4614} } // namespace v8::internal
4615
4616#endif // V8_OBJECTS_INL_H_