blob: cffad132a96765722dfb14f9f3b93d3363563157 [file] [log] [blame]
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001// Copyright 2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27//
28// Review notes:
29//
ager@chromium.org32912102009-01-16 10:38:43 +000030// - The use of macros in these inline functions may seem superfluous
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000031// but it is absolutely needed to make sure gcc generates optimal
32// code. gcc is not happy when attempting to inline too deep.
33//
34
35#ifndef V8_OBJECTS_INL_H_
36#define V8_OBJECTS_INL_H_
37
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +000038#include "elements.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000039#include "objects.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000040#include "contexts.h"
41#include "conversions-inl.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000042#include "heap.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000043#include "isolate.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000044#include "property.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000045#include "spaces.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000046#include "store-buffer.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000047#include "v8memory.h"
danno@chromium.orgfa458e42012-02-01 10:48:36 +000048#include "factory.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000049#include "incremental-marking.h"
50
kasperl@chromium.org71affb52009-05-26 05:44:31 +000051namespace v8 {
52namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000053
54PropertyDetails::PropertyDetails(Smi* smi) {
55 value_ = smi->value();
56}
57
58
59Smi* PropertyDetails::AsSmi() {
60 return Smi::FromInt(value_);
61}
62
63
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000064PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000065 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000066 return PropertyDetails(smi);
67}
68
69
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000070#define TYPE_CHECKER(type, instancetype) \
71 bool Object::Is##type() { \
72 return Object::IsHeapObject() && \
73 HeapObject::cast(this)->map()->instance_type() == instancetype; \
74 }
75
76
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000077#define CAST_ACCESSOR(type) \
78 type* type::cast(Object* object) { \
79 ASSERT(object->Is##type()); \
80 return reinterpret_cast<type*>(object); \
81 }
82
83
84#define INT_ACCESSORS(holder, name, offset) \
85 int holder::name() { return READ_INT_FIELD(this, offset); } \
86 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
87
88
89#define ACCESSORS(holder, name, type, offset) \
90 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000091 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000092 WRITE_FIELD(this, offset, value); \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000093 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000094 }
95
96
rossberg@chromium.org2c067b12012-03-19 11:01:52 +000097// Getter that returns a tagged Smi and setter that writes a tagged Smi.
98#define ACCESSORS_TO_SMI(holder, name, offset) \
99 Smi* holder::name() { return Smi::cast(READ_FIELD(this, offset)); } \
100 void holder::set_##name(Smi* value, WriteBarrierMode mode) { \
101 WRITE_FIELD(this, offset, value); \
102 }
103
104
105// Getter that returns a Smi as an int and writes an int as a Smi.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000106#define SMI_ACCESSORS(holder, name, offset) \
107 int holder::name() { \
108 Object* value = READ_FIELD(this, offset); \
109 return Smi::cast(value)->value(); \
110 } \
111 void holder::set_##name(int value) { \
112 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
113 }
114
115
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000116#define BOOL_GETTER(holder, field, name, offset) \
117 bool holder::name() { \
118 return BooleanBit::get(field(), offset); \
119 } \
120
121
122#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000123 bool holder::name() { \
124 return BooleanBit::get(field(), offset); \
125 } \
126 void holder::set_##name(bool value) { \
127 set_##field(BooleanBit::set(field(), offset, value)); \
128 }
129
130
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000131bool Object::IsFixedArrayBase() {
132 return IsFixedArray() || IsFixedDoubleArray();
133}
134
135
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000136bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
137 // There is a constraint on the object; check.
138 if (!this->IsJSObject()) return false;
139 // Fetch the constructor function of the object.
140 Object* cons_obj = JSObject::cast(this)->map()->constructor();
141 if (!cons_obj->IsJSFunction()) return false;
142 JSFunction* fun = JSFunction::cast(cons_obj);
143 // Iterate through the chain of inheriting function templates to
144 // see if the required one occurs.
145 for (Object* type = fun->shared()->function_data();
146 type->IsFunctionTemplateInfo();
147 type = FunctionTemplateInfo::cast(type)->parent_template()) {
148 if (type == expected) return true;
149 }
150 // Didn't find the required type in the inheritance chain.
151 return false;
152}
153
154
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000155bool Object::IsSmi() {
156 return HAS_SMI_TAG(this);
157}
158
159
160bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000161 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000162}
163
164
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000165bool Object::NonFailureIsHeapObject() {
166 ASSERT(!this->IsFailure());
167 return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0;
168}
169
170
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000171TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000172
173
174bool Object::IsString() {
175 return Object::IsHeapObject()
176 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
177}
178
179
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000180bool Object::IsSpecObject() {
181 return Object::IsHeapObject()
182 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
183}
184
185
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000186bool Object::IsSpecFunction() {
187 if (!Object::IsHeapObject()) return false;
188 InstanceType type = HeapObject::cast(this)->map()->instance_type();
189 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
190}
191
192
ager@chromium.org870a0b62008-11-04 11:43:05 +0000193bool Object::IsSymbol() {
194 if (!this->IsHeapObject()) return false;
195 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000196 // Because the symbol tag is non-zero and no non-string types have the
197 // symbol bit set we can test for symbols with a very simple test
198 // operation.
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000199 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000200 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
201 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000202}
203
204
205bool Object::IsConsString() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000206 if (!IsString()) return false;
207 return StringShape(String::cast(this)).IsCons();
208}
209
210
211bool Object::IsSlicedString() {
212 if (!IsString()) return false;
213 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000214}
215
216
ager@chromium.org870a0b62008-11-04 11:43:05 +0000217bool Object::IsSeqString() {
218 if (!IsString()) return false;
219 return StringShape(String::cast(this)).IsSequential();
220}
221
222
223bool Object::IsSeqAsciiString() {
224 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000225 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000226 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000227}
228
229
230bool Object::IsSeqTwoByteString() {
231 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000232 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000233 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000234}
235
236
237bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000238 if (!IsString()) return false;
239 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000240}
241
242
243bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000244 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000245 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000246 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000247}
248
249
250bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000251 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000252 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000253 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000254}
255
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000256bool Object::HasValidElements() {
257 // Dictionary is covered under FixedArray.
258 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
259}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000260
ager@chromium.org870a0b62008-11-04 11:43:05 +0000261StringShape::StringShape(String* str)
262 : type_(str->map()->instance_type()) {
263 set_valid();
264 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000265}
266
267
ager@chromium.org870a0b62008-11-04 11:43:05 +0000268StringShape::StringShape(Map* map)
269 : type_(map->instance_type()) {
270 set_valid();
271 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000272}
273
274
ager@chromium.org870a0b62008-11-04 11:43:05 +0000275StringShape::StringShape(InstanceType t)
276 : type_(static_cast<uint32_t>(t)) {
277 set_valid();
278 ASSERT((type_ & kIsNotStringMask) == kStringTag);
279}
280
281
282bool StringShape::IsSymbol() {
283 ASSERT(valid());
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000284 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000285 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000286}
287
288
ager@chromium.org5ec48922009-05-05 07:25:34 +0000289bool String::IsAsciiRepresentation() {
290 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000291 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000292}
293
294
ager@chromium.org5ec48922009-05-05 07:25:34 +0000295bool String::IsTwoByteRepresentation() {
296 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000297 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000298}
299
300
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000301bool String::IsAsciiRepresentationUnderneath() {
302 uint32_t type = map()->instance_type();
303 STATIC_ASSERT(kIsIndirectStringTag != 0);
304 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
305 ASSERT(IsFlat());
306 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
307 case kAsciiStringTag:
308 return true;
309 case kTwoByteStringTag:
310 return false;
311 default: // Cons or sliced string. Need to go deeper.
312 return GetUnderlying()->IsAsciiRepresentation();
313 }
314}
315
316
317bool String::IsTwoByteRepresentationUnderneath() {
318 uint32_t type = map()->instance_type();
319 STATIC_ASSERT(kIsIndirectStringTag != 0);
320 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
321 ASSERT(IsFlat());
322 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
323 case kAsciiStringTag:
324 return false;
325 case kTwoByteStringTag:
326 return true;
327 default: // Cons or sliced string. Need to go deeper.
328 return GetUnderlying()->IsTwoByteRepresentation();
329 }
330}
331
332
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000333bool String::HasOnlyAsciiChars() {
334 uint32_t type = map()->instance_type();
335 return (type & kStringEncodingMask) == kAsciiStringTag ||
336 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000337}
338
339
ager@chromium.org870a0b62008-11-04 11:43:05 +0000340bool StringShape::IsCons() {
341 return (type_ & kStringRepresentationMask) == kConsStringTag;
342}
343
344
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000345bool StringShape::IsSliced() {
346 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
347}
348
349
350bool StringShape::IsIndirect() {
351 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
352}
353
354
ager@chromium.org870a0b62008-11-04 11:43:05 +0000355bool StringShape::IsExternal() {
356 return (type_ & kStringRepresentationMask) == kExternalStringTag;
357}
358
359
360bool StringShape::IsSequential() {
361 return (type_ & kStringRepresentationMask) == kSeqStringTag;
362}
363
364
365StringRepresentationTag StringShape::representation_tag() {
366 uint32_t tag = (type_ & kStringRepresentationMask);
367 return static_cast<StringRepresentationTag>(tag);
368}
369
370
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000371uint32_t StringShape::encoding_tag() {
372 return type_ & kStringEncodingMask;
373}
374
375
ager@chromium.org870a0b62008-11-04 11:43:05 +0000376uint32_t StringShape::full_representation_tag() {
377 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
378}
379
380
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000381STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
382 Internals::kFullStringRepresentationMask);
383
384
ager@chromium.org870a0b62008-11-04 11:43:05 +0000385bool StringShape::IsSequentialAscii() {
386 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
387}
388
389
390bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000391 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000392}
393
394
395bool StringShape::IsExternalAscii() {
396 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
397}
398
399
400bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000401 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000402}
403
404
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000405STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
406 Internals::kExternalTwoByteRepresentationTag);
407
408
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000409uc32 FlatStringReader::Get(int index) {
410 ASSERT(0 <= index && index <= length_);
411 if (is_ascii_) {
412 return static_cast<const byte*>(start_)[index];
413 } else {
414 return static_cast<const uc16*>(start_)[index];
415 }
416}
417
418
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000419bool Object::IsNumber() {
420 return IsSmi() || IsHeapNumber();
421}
422
423
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000424TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
425TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000426
427
428bool Object::IsFiller() {
429 if (!Object::IsHeapObject()) return false;
430 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
431 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
432}
433
434
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000435TYPE_CHECKER(ExternalPixelArray, EXTERNAL_PIXEL_ARRAY_TYPE)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000436
437
ager@chromium.org3811b432009-10-28 14:53:37 +0000438bool Object::IsExternalArray() {
439 if (!Object::IsHeapObject())
440 return false;
441 InstanceType instance_type =
442 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000443 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
444 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000445}
446
447
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000448TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE)
449TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
450TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE)
451TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
452TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE)
453TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
454TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE)
455TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000456
457
lrn@chromium.org303ada72010-10-27 09:33:13 +0000458bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000459 return HAS_FAILURE_TAG(this);
460}
461
462
lrn@chromium.org303ada72010-10-27 09:33:13 +0000463bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000464 return HAS_FAILURE_TAG(this)
465 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
466}
467
468
lrn@chromium.org303ada72010-10-27 09:33:13 +0000469bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000470 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000471 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000472}
473
474
lrn@chromium.org303ada72010-10-27 09:33:13 +0000475bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000476 return this == Failure::Exception();
477}
478
479
lrn@chromium.org303ada72010-10-27 09:33:13 +0000480bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000481 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000482}
483
484
485Failure* Failure::cast(MaybeObject* obj) {
486 ASSERT(HAS_FAILURE_TAG(obj));
487 return reinterpret_cast<Failure*>(obj);
488}
489
490
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000491bool Object::IsJSReceiver() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000492 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000493 return IsHeapObject() &&
494 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
495}
496
497
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000498bool Object::IsJSObject() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000499 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
500 return IsHeapObject() &&
501 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000502}
503
504
505bool Object::IsJSProxy() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000506 if (!Object::IsHeapObject()) return false;
507 InstanceType type = HeapObject::cast(this)->map()->instance_type();
508 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000509}
510
511
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000512TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
513TYPE_CHECKER(JSSet, JS_SET_TYPE)
514TYPE_CHECKER(JSMap, JS_MAP_TYPE)
515TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
516TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
517TYPE_CHECKER(Map, MAP_TYPE)
518TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
519TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000520
521
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000522bool Object::IsDescriptorArray() {
523 return IsFixedArray();
524}
525
526
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000527bool Object::IsDeoptimizationInputData() {
528 // Must be a fixed array.
529 if (!IsFixedArray()) return false;
530
531 // There's no sure way to detect the difference between a fixed array and
532 // a deoptimization data array. Since this is used for asserts we can
533 // check that the length is zero or else the fixed size plus a multiple of
534 // the entry size.
535 int length = FixedArray::cast(this)->length();
536 if (length == 0) return true;
537
538 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
539 return length >= 0 &&
540 length % DeoptimizationInputData::kDeoptEntrySize == 0;
541}
542
543
544bool Object::IsDeoptimizationOutputData() {
545 if (!IsFixedArray()) return false;
546 // There's actually no way to see the difference between a fixed array and
547 // a deoptimization data array. Since this is used for asserts we can check
548 // that the length is plausible though.
549 if (FixedArray::cast(this)->length() % 2 != 0) return false;
550 return true;
551}
552
553
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000554bool Object::IsTypeFeedbackCells() {
555 if (!IsFixedArray()) return false;
556 // There's actually no way to see the difference between a fixed array and
557 // a cache cells array. Since this is used for asserts we can check that
558 // the length is plausible though.
559 if (FixedArray::cast(this)->length() % 2 != 0) return false;
560 return true;
561}
562
563
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000564bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000565 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000566 Map* map = HeapObject::cast(this)->map();
567 Heap* heap = map->GetHeap();
568 return (map == heap->function_context_map() ||
569 map == heap->catch_context_map() ||
570 map == heap->with_context_map() ||
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000571 map == heap->global_context_map() ||
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000572 map == heap->block_context_map() ||
573 map == heap->module_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000574 }
575 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000576}
577
578
579bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000580 return Object::IsHeapObject() &&
581 HeapObject::cast(this)->map() ==
582 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000583}
584
585
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000586bool Object::IsModuleContext() {
587 return Object::IsHeapObject() &&
588 HeapObject::cast(this)->map() ==
589 HeapObject::cast(this)->GetHeap()->module_context_map();
590}
591
592
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000593bool Object::IsScopeInfo() {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000594 return Object::IsHeapObject() &&
595 HeapObject::cast(this)->map() ==
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000596 HeapObject::cast(this)->GetHeap()->scope_info_map();
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000597}
598
599
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000600TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000601
602
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000603template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000604 return obj->IsJSFunction();
605}
606
607
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000608TYPE_CHECKER(Code, CODE_TYPE)
609TYPE_CHECKER(Oddball, ODDBALL_TYPE)
610TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
611TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000612TYPE_CHECKER(JSModule, JS_MODULE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000613TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000614TYPE_CHECKER(JSDate, JS_DATE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000615TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000616
617
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000618bool Object::IsStringWrapper() {
619 return IsJSValue() && JSValue::cast(this)->value()->IsString();
620}
621
622
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000623TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000624
625
626bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000627 return IsOddball() &&
628 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000629}
630
631
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000632TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
633TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000634
635
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000636template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000637 return obj->IsJSArray();
638}
639
640
641bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000642 return Object::IsHeapObject() &&
643 HeapObject::cast(this)->map() ==
644 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000645}
646
647
648bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000649 return IsHashTable() &&
650 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000651}
652
653
654bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000655 return IsHashTable() && this ==
656 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000657}
658
659
ager@chromium.orgac091b72010-05-05 07:34:42 +0000660bool Object::IsJSFunctionResultCache() {
661 if (!IsFixedArray()) return false;
662 FixedArray* self = FixedArray::cast(this);
663 int length = self->length();
664 if (length < JSFunctionResultCache::kEntriesIndex) return false;
665 if ((length - JSFunctionResultCache::kEntriesIndex)
666 % JSFunctionResultCache::kEntrySize != 0) {
667 return false;
668 }
669#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000670 if (FLAG_verify_heap) {
671 reinterpret_cast<JSFunctionResultCache*>(this)->
672 JSFunctionResultCacheVerify();
673 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000674#endif
675 return true;
676}
677
678
ricow@chromium.org65fae842010-08-25 15:26:24 +0000679bool Object::IsNormalizedMapCache() {
680 if (!IsFixedArray()) return false;
681 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
682 return false;
683 }
684#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000685 if (FLAG_verify_heap) {
686 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
687 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000688#endif
689 return true;
690}
691
692
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000693bool Object::IsCompilationCacheTable() {
694 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000695}
696
697
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000698bool Object::IsCodeCacheHashTable() {
699 return IsHashTable();
700}
701
702
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000703bool Object::IsPolymorphicCodeCacheHashTable() {
704 return IsHashTable();
705}
706
707
ager@chromium.org236ad962008-09-25 09:45:57 +0000708bool Object::IsMapCache() {
709 return IsHashTable();
710}
711
712
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000713bool Object::IsPrimitive() {
714 return IsOddball() || IsNumber() || IsString();
715}
716
717
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000718bool Object::IsJSGlobalProxy() {
719 bool result = IsHeapObject() &&
720 (HeapObject::cast(this)->map()->instance_type() ==
721 JS_GLOBAL_PROXY_TYPE);
722 ASSERT(!result || IsAccessCheckNeeded());
723 return result;
724}
725
726
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000727bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000728 if (!IsHeapObject()) return false;
729
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000730 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000731 return type == JS_GLOBAL_OBJECT_TYPE ||
732 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000733}
734
735
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000736TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
737TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000738
739
740bool Object::IsUndetectableObject() {
741 return IsHeapObject()
742 && HeapObject::cast(this)->map()->is_undetectable();
743}
744
745
746bool Object::IsAccessCheckNeeded() {
747 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000748 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000749}
750
751
752bool Object::IsStruct() {
753 if (!IsHeapObject()) return false;
754 switch (HeapObject::cast(this)->map()->instance_type()) {
755#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
756 STRUCT_LIST(MAKE_STRUCT_CASE)
757#undef MAKE_STRUCT_CASE
758 default: return false;
759 }
760}
761
762
763#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
764 bool Object::Is##Name() { \
765 return Object::IsHeapObject() \
766 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
767 }
768 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
769#undef MAKE_STRUCT_PREDICATE
770
771
772bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000773 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000774}
775
776
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000777bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000778 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
779}
780
781
782bool Object::IsTheHole() {
783 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000784}
785
786
787bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000788 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000789}
790
791
792bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000793 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000794}
795
796
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000797bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000798 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000799}
800
801
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000802double Object::Number() {
803 ASSERT(IsNumber());
804 return IsSmi()
805 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
806 : reinterpret_cast<HeapNumber*>(this)->value();
807}
808
809
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000810bool Object::IsNaN() {
811 return this->IsHeapNumber() && isnan(HeapNumber::cast(this)->value());
812}
813
814
lrn@chromium.org303ada72010-10-27 09:33:13 +0000815MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000816 if (IsSmi()) return this;
817 if (IsHeapNumber()) {
818 double value = HeapNumber::cast(this)->value();
819 int int_value = FastD2I(value);
820 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
821 return Smi::FromInt(int_value);
822 }
823 }
824 return Failure::Exception();
825}
826
827
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000828bool Object::HasSpecificClassOf(String* name) {
829 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
830}
831
832
lrn@chromium.org303ada72010-10-27 09:33:13 +0000833MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000834 // GetElement can trigger a getter which can cause allocation.
835 // This was not always the case. This ASSERT is here to catch
836 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000837 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000838 return GetElementWithReceiver(this, index);
839}
840
841
lrn@chromium.org303ada72010-10-27 09:33:13 +0000842Object* Object::GetElementNoExceptionThrown(uint32_t index) {
843 MaybeObject* maybe = GetElementWithReceiver(this, index);
844 ASSERT(!maybe->IsFailure());
845 Object* result = NULL; // Initialization to please compiler.
846 maybe->ToObject(&result);
847 return result;
848}
849
850
851MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000852 PropertyAttributes attributes;
853 return GetPropertyWithReceiver(this, key, &attributes);
854}
855
856
lrn@chromium.org303ada72010-10-27 09:33:13 +0000857MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000858 return GetPropertyWithReceiver(this, key, attributes);
859}
860
861
862#define FIELD_ADDR(p, offset) \
863 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
864
865#define READ_FIELD(p, offset) \
866 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
867
868#define WRITE_FIELD(p, offset, value) \
869 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
870
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000871#define WRITE_BARRIER(heap, object, offset, value) \
872 heap->incremental_marking()->RecordWrite( \
873 object, HeapObject::RawField(object, offset), value); \
874 if (heap->InNewSpace(value)) { \
875 heap->RecordWrite(object->address(), offset); \
876 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000877
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000878#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
879 if (mode == UPDATE_WRITE_BARRIER) { \
880 heap->incremental_marking()->RecordWrite( \
881 object, HeapObject::RawField(object, offset), value); \
882 if (heap->InNewSpace(value)) { \
883 heap->RecordWrite(object->address(), offset); \
884 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000885 }
886
lrn@chromium.org7516f052011-03-30 08:52:27 +0000887#ifndef V8_TARGET_ARCH_MIPS
888 #define READ_DOUBLE_FIELD(p, offset) \
889 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
890#else // V8_TARGET_ARCH_MIPS
891 // Prevent gcc from using load-double (mips ldc1) on (possibly)
892 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000893 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000894 union conversion {
895 double d;
896 uint32_t u[2];
897 } c;
898 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
899 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
900 return c.d;
901 }
902 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
903#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000904
lrn@chromium.org7516f052011-03-30 08:52:27 +0000905#ifndef V8_TARGET_ARCH_MIPS
906 #define WRITE_DOUBLE_FIELD(p, offset, value) \
907 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
908#else // V8_TARGET_ARCH_MIPS
909 // Prevent gcc from using store-double (mips sdc1) on (possibly)
910 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000911 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000912 double value) {
913 union conversion {
914 double d;
915 uint32_t u[2];
916 } c;
917 c.d = value;
918 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
919 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
920 }
921 #define WRITE_DOUBLE_FIELD(p, offset, value) \
922 write_double_field(p, offset, value)
923#endif // V8_TARGET_ARCH_MIPS
924
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000925
926#define READ_INT_FIELD(p, offset) \
927 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
928
929#define WRITE_INT_FIELD(p, offset, value) \
930 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
931
ager@chromium.org3e875802009-06-29 08:26:34 +0000932#define READ_INTPTR_FIELD(p, offset) \
933 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
934
935#define WRITE_INTPTR_FIELD(p, offset, value) \
936 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
937
ager@chromium.org7c537e22008-10-16 08:43:32 +0000938#define READ_UINT32_FIELD(p, offset) \
939 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
940
941#define WRITE_UINT32_FIELD(p, offset, value) \
942 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
943
danno@chromium.org88aa0582012-03-23 15:11:57 +0000944#define READ_INT64_FIELD(p, offset) \
945 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)))
946
947#define WRITE_INT64_FIELD(p, offset, value) \
948 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
949
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000950#define READ_SHORT_FIELD(p, offset) \
951 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
952
953#define WRITE_SHORT_FIELD(p, offset, value) \
954 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
955
956#define READ_BYTE_FIELD(p, offset) \
957 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
958
959#define WRITE_BYTE_FIELD(p, offset, value) \
960 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
961
962
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000963Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
964 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000965}
966
967
968int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000969 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000970}
971
972
973Smi* Smi::FromInt(int value) {
974 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000975 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000976 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000977 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000978 return reinterpret_cast<Smi*>(tagged_value);
979}
980
981
982Smi* Smi::FromIntptr(intptr_t value) {
983 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000984 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
985 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000986}
987
988
989Failure::Type Failure::type() const {
990 return static_cast<Type>(value() & kFailureTypeTagMask);
991}
992
993
994bool Failure::IsInternalError() const {
995 return type() == INTERNAL_ERROR;
996}
997
998
999bool Failure::IsOutOfMemoryException() const {
1000 return type() == OUT_OF_MEMORY_EXCEPTION;
1001}
1002
1003
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001004AllocationSpace Failure::allocation_space() const {
1005 ASSERT_EQ(RETRY_AFTER_GC, type());
1006 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1007 & kSpaceTagMask);
1008}
1009
1010
1011Failure* Failure::InternalError() {
1012 return Construct(INTERNAL_ERROR);
1013}
1014
1015
1016Failure* Failure::Exception() {
1017 return Construct(EXCEPTION);
1018}
1019
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001020
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001021Failure* Failure::OutOfMemoryException() {
1022 return Construct(OUT_OF_MEMORY_EXCEPTION);
1023}
1024
1025
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001026intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001027 return static_cast<intptr_t>(
1028 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001029}
1030
1031
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001032Failure* Failure::RetryAfterGC() {
1033 return RetryAfterGC(NEW_SPACE);
1034}
1035
1036
1037Failure* Failure::RetryAfterGC(AllocationSpace space) {
1038 ASSERT((space & ~kSpaceTagMask) == 0);
1039 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001040}
1041
1042
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001043Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001044 uintptr_t info =
1045 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001046 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001047 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001048}
1049
1050
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001051bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001052#ifdef DEBUG
1053 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1054#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001055
1056#ifdef V8_TARGET_ARCH_X64
1057 // To be representable as a long smi, the value must be a 32-bit integer.
1058 bool result = (value == static_cast<int32_t>(value));
1059#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001060 // To be representable as an tagged small integer, the two
1061 // most-significant bits of 'value' must be either 00 or 11 due to
1062 // sign-extension. To check this we add 01 to the two
1063 // most-significant bits, and check if the most-significant bit is 0
1064 //
1065 // CAUTION: The original code below:
1066 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1067 // may lead to incorrect results according to the C language spec, and
1068 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1069 // compiler may produce undefined results in case of signed integer
1070 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001071 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001072#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001073 ASSERT(result == in_range);
1074 return result;
1075}
1076
1077
kasper.lund7276f142008-07-30 08:49:36 +00001078MapWord MapWord::FromMap(Map* map) {
1079 return MapWord(reinterpret_cast<uintptr_t>(map));
1080}
1081
1082
1083Map* MapWord::ToMap() {
1084 return reinterpret_cast<Map*>(value_);
1085}
1086
1087
1088bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001089 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001090}
1091
1092
1093MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001094 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1095 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001096}
1097
1098
1099HeapObject* MapWord::ToForwardingAddress() {
1100 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001101 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001102}
1103
1104
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001105#ifdef DEBUG
1106void HeapObject::VerifyObjectField(int offset) {
1107 VerifyPointer(READ_FIELD(this, offset));
1108}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001109
1110void HeapObject::VerifySmiField(int offset) {
1111 ASSERT(READ_FIELD(this, offset)->IsSmi());
1112}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001113#endif
1114
1115
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001116Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001117 Heap* heap =
1118 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1119 ASSERT(heap != NULL);
1120 ASSERT(heap->isolate() == Isolate::Current());
1121 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001122}
1123
1124
1125Isolate* HeapObject::GetIsolate() {
1126 return GetHeap()->isolate();
1127}
1128
1129
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001130Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001131 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001132}
1133
1134
1135void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001136 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001137 if (value != NULL) {
1138 // TODO(1600) We are passing NULL as a slot because maps can never be on
1139 // evacuation candidate.
1140 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1141 }
1142}
1143
1144
1145// Unsafe accessor omitting write barrier.
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001146void HeapObject::set_map_no_write_barrier(Map* value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001147 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001148}
1149
1150
kasper.lund7276f142008-07-30 08:49:36 +00001151MapWord HeapObject::map_word() {
1152 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1153}
1154
1155
1156void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001157 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001158 // here.
1159 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1160}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001161
1162
1163HeapObject* HeapObject::FromAddress(Address address) {
1164 ASSERT_TAG_ALIGNED(address);
1165 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1166}
1167
1168
1169Address HeapObject::address() {
1170 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1171}
1172
1173
1174int HeapObject::Size() {
1175 return SizeFromMap(map());
1176}
1177
1178
1179void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1180 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1181 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1182}
1183
1184
1185void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1186 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1187}
1188
1189
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001190double HeapNumber::value() {
1191 return READ_DOUBLE_FIELD(this, kValueOffset);
1192}
1193
1194
1195void HeapNumber::set_value(double value) {
1196 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1197}
1198
1199
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001200int HeapNumber::get_exponent() {
1201 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1202 kExponentShift) - kExponentBias;
1203}
1204
1205
1206int HeapNumber::get_sign() {
1207 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1208}
1209
1210
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001211ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001212
1213
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001214Object** FixedArray::GetFirstElementAddress() {
1215 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1216}
1217
1218
1219bool FixedArray::ContainsOnlySmisOrHoles() {
1220 Object* the_hole = GetHeap()->the_hole_value();
1221 Object** current = GetFirstElementAddress();
1222 for (int i = 0; i < length(); ++i) {
1223 Object* candidate = *current++;
1224 if (!candidate->IsSmi() && candidate != the_hole) return false;
1225 }
1226 return true;
1227}
1228
1229
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001230FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001231 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001232 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001233}
1234
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001235
1236void JSObject::ValidateElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001237#if DEBUG
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001238 if (FLAG_enable_slow_asserts) {
1239 ElementsAccessor* accessor = GetElementsAccessor();
1240 accessor->Validate(this);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001241 }
1242#endif
1243}
1244
1245
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001246MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001247 ValidateElements();
1248 ElementsKind elements_kind = map()->elements_kind();
1249 if (!IsFastObjectElementsKind(elements_kind)) {
1250 if (IsFastHoleyElementsKind(elements_kind)) {
1251 return TransitionElementsKind(FAST_HOLEY_ELEMENTS);
1252 } else {
1253 return TransitionElementsKind(FAST_ELEMENTS);
1254 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001255 }
1256 return this;
1257}
1258
1259
1260MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001261 uint32_t count,
1262 EnsureElementsMode mode) {
1263 ElementsKind current_kind = map()->elements_kind();
1264 ElementsKind target_kind = current_kind;
1265 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001266 bool is_holey = IsFastHoleyElementsKind(current_kind);
1267 if (current_kind == FAST_HOLEY_ELEMENTS) return this;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001268 Heap* heap = GetHeap();
1269 Object* the_hole = heap->the_hole_value();
1270 Object* heap_number_map = heap->heap_number_map();
1271 for (uint32_t i = 0; i < count; ++i) {
1272 Object* current = *objects++;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001273 if (current == the_hole) {
1274 is_holey = true;
1275 target_kind = GetHoleyElementsKind(target_kind);
1276 } else if (!current->IsSmi()) {
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001277 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001278 HeapObject::cast(current)->map() == heap_number_map &&
1279 IsFastSmiElementsKind(target_kind)) {
1280 if (is_holey) {
1281 target_kind = FAST_HOLEY_DOUBLE_ELEMENTS;
1282 } else {
1283 target_kind = FAST_DOUBLE_ELEMENTS;
1284 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001285 } else {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001286 if (!current->IsNumber()) {
1287 if (is_holey) {
1288 target_kind = FAST_HOLEY_ELEMENTS;
1289 break;
1290 } else {
1291 target_kind = FAST_ELEMENTS;
1292 }
1293 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001294 }
1295 }
1296 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001297
1298 if (target_kind != current_kind) {
1299 return TransitionElementsKind(target_kind);
1300 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001301 return this;
1302}
1303
1304
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001305MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001306 uint32_t length,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001307 EnsureElementsMode mode) {
1308 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1309 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1310 elements->map() == GetHeap()->fixed_cow_array_map());
1311 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1312 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1313 }
1314 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001315 return EnsureCanContainElements(objects, length, mode);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001316 }
1317
1318 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001319 if (GetElementsKind() == FAST_HOLEY_SMI_ELEMENTS) {
1320 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS);
1321 } else if (GetElementsKind() == FAST_SMI_ELEMENTS) {
1322 FixedDoubleArray* double_array = FixedDoubleArray::cast(elements);
1323 for (uint32_t i = 0; i < length; ++i) {
1324 if (double_array->is_the_hole(i)) {
1325 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS);
1326 }
1327 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001328 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1329 }
1330
1331 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001332}
1333
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001334
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001335MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
1336 ElementsKind to_kind) {
1337 Map* current_map = map();
1338 ElementsKind from_kind = current_map->elements_kind();
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001339 if (from_kind == to_kind) return current_map;
1340
1341 Context* global_context = isolate->context()->global_context();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001342 Object* maybe_array_maps = global_context->js_array_maps();
1343 if (maybe_array_maps->IsFixedArray()) {
1344 FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
1345 if (array_maps->get(from_kind) == current_map) {
1346 Object* maybe_transitioned_map = array_maps->get(to_kind);
1347 if (maybe_transitioned_map->IsMap()) {
1348 return Map::cast(maybe_transitioned_map);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001349 }
1350 }
1351 }
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001352
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001353 return GetElementsTransitionMapSlow(to_kind);
1354}
1355
1356
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001357void JSObject::set_map_and_elements(Map* new_map,
1358 FixedArrayBase* value,
1359 WriteBarrierMode mode) {
1360 ASSERT(value->HasValidElements());
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001361 if (new_map != NULL) {
1362 if (mode == UPDATE_WRITE_BARRIER) {
1363 set_map(new_map);
1364 } else {
1365 ASSERT(mode == SKIP_WRITE_BARRIER);
1366 set_map_no_write_barrier(new_map);
1367 }
1368 }
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001369 ASSERT((map()->has_fast_smi_or_object_elements() ||
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001370 (value == GetHeap()->empty_fixed_array())) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001371 (value->map() == GetHeap()->fixed_array_map() ||
1372 value->map() == GetHeap()->fixed_cow_array_map()));
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001373 ASSERT((value == GetHeap()->empty_fixed_array()) ||
1374 (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001375 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001376 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001377}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001378
1379
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001380void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1381 set_map_and_elements(NULL, value, mode);
1382}
1383
1384
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001385void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001386 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1387 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001388}
1389
1390
1391void JSObject::initialize_elements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001392 ASSERT(map()->has_fast_smi_or_object_elements() ||
danno@chromium.org2c26cb12012-05-03 09:06:43 +00001393 map()->has_fast_double_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001394 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1395 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001396}
1397
1398
lrn@chromium.org303ada72010-10-27 09:33:13 +00001399MaybeObject* JSObject::ResetElements() {
1400 Object* obj;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001401 ElementsKind elements_kind = GetInitialFastElementsKind();
1402 if (!FLAG_smi_only_arrays) {
1403 elements_kind = FastSmiToObjectElementsKind(elements_kind);
1404 }
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001405 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(),
1406 elements_kind);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001407 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001408 set_map(Map::cast(obj));
1409 initialize_elements();
1410 return this;
1411}
1412
1413
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001414ACCESSORS(Oddball, to_string, String, kToStringOffset)
1415ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1416
1417
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001418byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001419 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001420}
1421
1422
1423void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001424 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001425}
1426
1427
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001428Object* JSGlobalPropertyCell::value() {
1429 return READ_FIELD(this, kValueOffset);
1430}
1431
1432
1433void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1434 // The write barrier is not used for global property cells.
1435 ASSERT(!val->IsJSGlobalPropertyCell());
1436 WRITE_FIELD(this, kValueOffset, val);
1437}
1438
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001439
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001440int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001441 InstanceType type = map()->instance_type();
1442 // Check for the most common kind of JavaScript object before
1443 // falling into the generic switch. This speeds up the internal
1444 // field operations considerably on average.
1445 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1446 switch (type) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001447 case JS_MODULE_TYPE:
1448 return JSModule::kSize;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001449 case JS_GLOBAL_PROXY_TYPE:
1450 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001451 case JS_GLOBAL_OBJECT_TYPE:
1452 return JSGlobalObject::kSize;
1453 case JS_BUILTINS_OBJECT_TYPE:
1454 return JSBuiltinsObject::kSize;
1455 case JS_FUNCTION_TYPE:
1456 return JSFunction::kSize;
1457 case JS_VALUE_TYPE:
1458 return JSValue::kSize;
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00001459 case JS_DATE_TYPE:
1460 return JSDate::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001461 case JS_ARRAY_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001462 return JSArray::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001463 case JS_WEAK_MAP_TYPE:
1464 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001465 case JS_REGEXP_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001466 return JSRegExp::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001467 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001468 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001469 case JS_MESSAGE_OBJECT_TYPE:
1470 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001471 default:
1472 UNREACHABLE();
1473 return 0;
1474 }
1475}
1476
1477
1478int JSObject::GetInternalFieldCount() {
1479 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001480 // Make sure to adjust for the number of in-object properties. These
1481 // properties do contribute to the size, but are not internal fields.
1482 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1483 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001484}
1485
1486
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001487int JSObject::GetInternalFieldOffset(int index) {
1488 ASSERT(index < GetInternalFieldCount() && index >= 0);
1489 return GetHeaderSize() + (kPointerSize * index);
1490}
1491
1492
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001493Object* JSObject::GetInternalField(int index) {
1494 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001495 // Internal objects do follow immediately after the header, whereas in-object
1496 // properties are at the end of the object. Therefore there is no need
1497 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001498 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1499}
1500
1501
1502void JSObject::SetInternalField(int index, Object* value) {
1503 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001504 // Internal objects do follow immediately after the header, whereas in-object
1505 // properties are at the end of the object. Therefore there is no need
1506 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001507 int offset = GetHeaderSize() + (kPointerSize * index);
1508 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001509 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001510}
1511
1512
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001513void JSObject::SetInternalField(int index, Smi* value) {
1514 ASSERT(index < GetInternalFieldCount() && index >= 0);
1515 // Internal objects do follow immediately after the header, whereas in-object
1516 // properties are at the end of the object. Therefore there is no need
1517 // to adjust the index here.
1518 int offset = GetHeaderSize() + (kPointerSize * index);
1519 WRITE_FIELD(this, offset, value);
1520}
1521
1522
ager@chromium.org7c537e22008-10-16 08:43:32 +00001523// Access fast-case object properties at index. The use of these routines
1524// is needed to correctly distinguish between properties stored in-object and
1525// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001526Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001527 // Adjust for the number of properties stored in the object.
1528 index -= map()->inobject_properties();
1529 if (index < 0) {
1530 int offset = map()->instance_size() + (index * kPointerSize);
1531 return READ_FIELD(this, offset);
1532 } else {
1533 ASSERT(index < properties()->length());
1534 return properties()->get(index);
1535 }
1536}
1537
1538
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001539Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001540 // Adjust for the number of properties stored in the object.
1541 index -= map()->inobject_properties();
1542 if (index < 0) {
1543 int offset = map()->instance_size() + (index * kPointerSize);
1544 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001545 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001546 } else {
1547 ASSERT(index < properties()->length());
1548 properties()->set(index, value);
1549 }
1550 return value;
1551}
1552
1553
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001554int JSObject::GetInObjectPropertyOffset(int index) {
1555 // Adjust for the number of properties stored in the object.
1556 index -= map()->inobject_properties();
1557 ASSERT(index < 0);
1558 return map()->instance_size() + (index * kPointerSize);
1559}
1560
1561
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001562Object* JSObject::InObjectPropertyAt(int index) {
1563 // Adjust for the number of properties stored in the object.
1564 index -= map()->inobject_properties();
1565 ASSERT(index < 0);
1566 int offset = map()->instance_size() + (index * kPointerSize);
1567 return READ_FIELD(this, offset);
1568}
1569
1570
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001571Object* JSObject::InObjectPropertyAtPut(int index,
1572 Object* value,
1573 WriteBarrierMode mode) {
1574 // Adjust for the number of properties stored in the object.
1575 index -= map()->inobject_properties();
1576 ASSERT(index < 0);
1577 int offset = map()->instance_size() + (index * kPointerSize);
1578 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001579 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001580 return value;
1581}
1582
1583
1584
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001585void JSObject::InitializeBody(Map* map,
1586 Object* pre_allocated_value,
1587 Object* filler_value) {
1588 ASSERT(!filler_value->IsHeapObject() ||
1589 !GetHeap()->InNewSpace(filler_value));
1590 ASSERT(!pre_allocated_value->IsHeapObject() ||
1591 !GetHeap()->InNewSpace(pre_allocated_value));
1592 int size = map->instance_size();
1593 int offset = kHeaderSize;
1594 if (filler_value != pre_allocated_value) {
1595 int pre_allocated = map->pre_allocated_property_fields();
1596 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1597 for (int i = 0; i < pre_allocated; i++) {
1598 WRITE_FIELD(this, offset, pre_allocated_value);
1599 offset += kPointerSize;
1600 }
1601 }
1602 while (offset < size) {
1603 WRITE_FIELD(this, offset, filler_value);
1604 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001605 }
1606}
1607
1608
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001609bool JSObject::HasFastProperties() {
1610 return !properties()->IsDictionary();
1611}
1612
1613
1614int JSObject::MaxFastProperties() {
1615 // Allow extra fast properties if the object has more than
1616 // kMaxFastProperties in-object properties. When this is the case,
1617 // it is very unlikely that the object is being used as a dictionary
1618 // and there is a good chance that allowing more map transitions
1619 // will be worth it.
1620 return Max(map()->inobject_properties(), kMaxFastProperties);
1621}
1622
1623
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001624void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001625 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001626 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001627 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001628 }
1629}
1630
1631
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001632bool Object::ToArrayIndex(uint32_t* index) {
1633 if (IsSmi()) {
1634 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001635 if (value < 0) return false;
1636 *index = value;
1637 return true;
1638 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001639 if (IsHeapNumber()) {
1640 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001641 uint32_t uint_value = static_cast<uint32_t>(value);
1642 if (value == static_cast<double>(uint_value)) {
1643 *index = uint_value;
1644 return true;
1645 }
1646 }
1647 return false;
1648}
1649
1650
1651bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1652 if (!this->IsJSValue()) return false;
1653
1654 JSValue* js_value = JSValue::cast(this);
1655 if (!js_value->value()->IsString()) return false;
1656
1657 String* str = String::cast(js_value->value());
1658 if (index >= (uint32_t)str->length()) return false;
1659
1660 return true;
1661}
1662
1663
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001664FixedArrayBase* FixedArrayBase::cast(Object* object) {
1665 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1666 return reinterpret_cast<FixedArrayBase*>(object);
1667}
1668
1669
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001670Object* FixedArray::get(int index) {
1671 ASSERT(index >= 0 && index < this->length());
1672 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1673}
1674
1675
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001676bool FixedArray::is_the_hole(int index) {
1677 return get(index) == GetHeap()->the_hole_value();
1678}
1679
1680
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001681void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001682 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001683 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001684 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1685 int offset = kHeaderSize + index * kPointerSize;
1686 WRITE_FIELD(this, offset, value);
1687}
1688
1689
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001690void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001691 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001692 ASSERT(index >= 0 && index < this->length());
1693 int offset = kHeaderSize + index * kPointerSize;
1694 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001695 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001696}
1697
1698
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001699inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1700 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1701}
1702
1703
1704inline double FixedDoubleArray::hole_nan_as_double() {
1705 return BitCast<double, uint64_t>(kHoleNanInt64);
1706}
1707
1708
1709inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1710 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1711 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1712 return OS::nan_value();
1713}
1714
1715
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001716double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001717 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1718 map() != HEAP->fixed_array_map());
1719 ASSERT(index >= 0 && index < this->length());
1720 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1721 ASSERT(!is_the_hole_nan(result));
1722 return result;
1723}
1724
danno@chromium.org88aa0582012-03-23 15:11:57 +00001725int64_t FixedDoubleArray::get_representation(int index) {
1726 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1727 map() != HEAP->fixed_array_map());
1728 ASSERT(index >= 0 && index < this->length());
1729 return READ_INT64_FIELD(this, kHeaderSize + index * kDoubleSize);
1730}
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001731
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001732MaybeObject* FixedDoubleArray::get(int index) {
1733 if (is_the_hole(index)) {
1734 return GetHeap()->the_hole_value();
1735 } else {
1736 return GetHeap()->NumberFromDouble(get_scalar(index));
1737 }
1738}
1739
1740
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001741void FixedDoubleArray::set(int index, double value) {
1742 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1743 map() != HEAP->fixed_array_map());
1744 int offset = kHeaderSize + index * kDoubleSize;
1745 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1746 WRITE_DOUBLE_FIELD(this, offset, value);
1747}
1748
1749
1750void FixedDoubleArray::set_the_hole(int index) {
1751 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1752 map() != HEAP->fixed_array_map());
1753 int offset = kHeaderSize + index * kDoubleSize;
1754 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1755}
1756
1757
1758bool FixedDoubleArray::is_the_hole(int index) {
1759 int offset = kHeaderSize + index * kDoubleSize;
1760 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1761}
1762
1763
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001764WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001765 Heap* heap = GetHeap();
1766 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1767 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001768 return UPDATE_WRITE_BARRIER;
1769}
1770
1771
1772void FixedArray::set(int index,
1773 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001774 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001775 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001776 ASSERT(index >= 0 && index < this->length());
1777 int offset = kHeaderSize + index * kPointerSize;
1778 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001779 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001780}
1781
1782
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001783void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1784 int index,
1785 Object* value) {
1786 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
1787 ASSERT(index >= 0 && index < array->length());
1788 int offset = kHeaderSize + index * kPointerSize;
1789 WRITE_FIELD(array, offset, value);
1790 Heap* heap = array->GetHeap();
1791 if (heap->InNewSpace(value)) {
1792 heap->RecordWrite(array->address(), offset);
1793 }
1794}
1795
1796
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001797void FixedArray::NoWriteBarrierSet(FixedArray* array,
1798 int index,
1799 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001800 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001801 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001802 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001803 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1804}
1805
1806
1807void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001808 ASSERT(map() != HEAP->fixed_cow_array_map());
1809 set_undefined(GetHeap(), index);
1810}
1811
1812
1813void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001814 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001815 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001816 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001817 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001818}
1819
1820
ager@chromium.org236ad962008-09-25 09:45:57 +00001821void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001822 set_null(GetHeap(), index);
1823}
1824
1825
1826void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001827 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001828 ASSERT(!heap->InNewSpace(heap->null_value()));
1829 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001830}
1831
1832
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001833void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001834 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001835 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001836 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1837 WRITE_FIELD(this,
1838 kHeaderSize + index * kPointerSize,
1839 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001840}
1841
1842
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001843void FixedArray::set_unchecked(int index, Smi* value) {
1844 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1845 int offset = kHeaderSize + index * kPointerSize;
1846 WRITE_FIELD(this, offset, value);
1847}
1848
1849
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001850void FixedArray::set_unchecked(Heap* heap,
1851 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001852 Object* value,
1853 WriteBarrierMode mode) {
1854 int offset = kHeaderSize + index * kPointerSize;
1855 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001856 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001857}
1858
1859
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001860void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001861 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001862 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1863 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001864}
1865
1866
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001867Object** FixedArray::data_start() {
1868 return HeapObject::RawField(this, kHeaderSize);
1869}
1870
1871
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001872bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001873 ASSERT(this->IsSmi() ||
1874 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001875 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001876 return this->IsSmi() || length() <= kFirstIndex;
1877}
1878
1879
1880int DescriptorArray::bit_field3_storage() {
1881 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1882 return Smi::cast(storage)->value();
1883}
1884
1885void DescriptorArray::set_bit_field3_storage(int value) {
1886 ASSERT(!IsEmpty());
1887 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001888}
1889
1890
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001891void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1892 int first,
1893 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001894 Object* tmp = array->get(first);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001895 NoIncrementalWriteBarrierSet(array, first, array->get(second));
1896 NoIncrementalWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001897}
1898
1899
1900int DescriptorArray::Search(String* name) {
1901 SLOW_ASSERT(IsSortedNoDuplicates());
1902
1903 // Check for empty descriptor array.
1904 int nof = number_of_descriptors();
1905 if (nof == 0) return kNotFound;
1906
1907 // Fast case: do linear search for small arrays.
1908 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001909 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001910 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001911 }
1912
1913 // Slow case: perform binary search.
1914 return BinarySearch(name, 0, nof - 1);
1915}
1916
1917
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001918int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001919 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001920 if (number == DescriptorLookupCache::kAbsent) {
1921 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001922 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001923 }
1924 return number;
1925}
1926
1927
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001928String* DescriptorArray::GetKey(int descriptor_number) {
1929 ASSERT(descriptor_number < number_of_descriptors());
1930 return String::cast(get(ToKeyIndex(descriptor_number)));
1931}
1932
1933
verwaest@chromium.org37141392012-05-31 13:27:02 +00001934Object** DescriptorArray::GetValueSlot(int descriptor_number) {
1935 ASSERT(descriptor_number < number_of_descriptors());
1936 return GetContentArray()->data_start() + ToValueIndex(descriptor_number);
1937}
1938
1939
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001940Object* DescriptorArray::GetValue(int descriptor_number) {
1941 ASSERT(descriptor_number < number_of_descriptors());
1942 return GetContentArray()->get(ToValueIndex(descriptor_number));
1943}
1944
1945
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001946PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001947 ASSERT(descriptor_number < number_of_descriptors());
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001948 Object* details = GetContentArray()->get(ToDetailsIndex(descriptor_number));
1949 return PropertyDetails(Smi::cast(details));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001950}
1951
1952
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001953PropertyType DescriptorArray::GetType(int descriptor_number) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001954 return GetDetails(descriptor_number).type();
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001955}
1956
1957
1958int DescriptorArray::GetFieldIndex(int descriptor_number) {
1959 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1960}
1961
1962
1963JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1964 return JSFunction::cast(GetValue(descriptor_number));
1965}
1966
1967
1968Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1969 ASSERT(GetType(descriptor_number) == CALLBACKS);
1970 return GetValue(descriptor_number);
1971}
1972
1973
1974AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1975 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001976 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001977 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001978}
1979
1980
1981bool DescriptorArray::IsProperty(int descriptor_number) {
ulan@chromium.org9a21ec42012-03-06 08:42:24 +00001982 Entry entry(this, descriptor_number);
1983 return IsPropertyDescriptor(&entry);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001984}
1985
1986
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001987bool DescriptorArray::IsTransitionOnly(int descriptor_number) {
1988 switch (GetType(descriptor_number)) {
1989 case MAP_TRANSITION:
1990 case CONSTANT_TRANSITION:
1991 case ELEMENTS_TRANSITION:
1992 return true;
1993 case CALLBACKS: {
1994 Object* value = GetValue(descriptor_number);
1995 if (!value->IsAccessorPair()) return false;
1996 AccessorPair* accessors = AccessorPair::cast(value);
1997 return accessors->getter()->IsMap() && accessors->setter()->IsMap();
1998 }
1999 case NORMAL:
2000 case FIELD:
2001 case CONSTANT_FUNCTION:
2002 case HANDLER:
2003 case INTERCEPTOR:
2004 case NULL_DESCRIPTOR:
2005 return false;
2006 }
2007 UNREACHABLE(); // Keep the compiler happy.
2008 return false;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002009}
2010
2011
2012bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
2013 return GetType(descriptor_number) == NULL_DESCRIPTOR;
2014}
2015
2016
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002017void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2018 desc->Init(GetKey(descriptor_number),
2019 GetValue(descriptor_number),
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002020 GetDetails(descriptor_number));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002021}
2022
2023
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002024void DescriptorArray::Set(int descriptor_number,
2025 Descriptor* desc,
2026 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002027 // Range check.
2028 ASSERT(descriptor_number < number_of_descriptors());
2029
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002030 NoIncrementalWriteBarrierSet(this,
2031 ToKeyIndex(descriptor_number),
2032 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002033 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002034 NoIncrementalWriteBarrierSet(content_array,
2035 ToValueIndex(descriptor_number),
2036 desc->GetValue());
2037 NoIncrementalWriteBarrierSet(content_array,
2038 ToDetailsIndex(descriptor_number),
2039 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002040}
2041
2042
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002043void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2044 int first, int second) {
2045 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002046 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002047 NoIncrementalWriteBarrierSwap(content_array,
2048 ToValueIndex(first),
2049 ToValueIndex(second));
2050 NoIncrementalWriteBarrierSwap(content_array,
2051 ToDetailsIndex(first),
2052 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002053}
2054
2055
2056DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
2057 : marking_(array->GetHeap()->incremental_marking()) {
2058 marking_->EnterNoMarkingScope();
2059 if (array->number_of_descriptors() > 0) {
2060 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
2061 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
2062 }
2063}
2064
2065
2066DescriptorArray::WhitenessWitness::~WhitenessWitness() {
2067 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002068}
2069
2070
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002071template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002072int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2073 const int kMinCapacity = 32;
2074 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2075 if (capacity < kMinCapacity) {
2076 capacity = kMinCapacity; // Guarantee min capacity.
2077 }
2078 return capacity;
2079}
2080
2081
2082template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002083int HashTable<Shape, Key>::FindEntry(Key key) {
2084 return FindEntry(GetIsolate(), key);
2085}
2086
2087
2088// Find entry for key otherwise return kNotFound.
2089template<typename Shape, typename Key>
2090int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2091 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002092 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002093 uint32_t count = 1;
2094 // EnsureCapacity will guarantee the hash table is never full.
2095 while (true) {
2096 Object* element = KeyAt(entry);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002097 // Empty entry.
2098 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2099 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002100 Shape::IsMatch(key, element)) return entry;
2101 entry = NextProbe(entry, count++, capacity);
2102 }
2103 return kNotFound;
2104}
2105
2106
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002107bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002108 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002109 if (!max_index_object->IsSmi()) return false;
2110 return 0 !=
2111 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2112}
2113
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002114uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002115 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002116 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002117 if (!max_index_object->IsSmi()) return 0;
2118 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2119 return value >> kRequiresSlowElementsTagSize;
2120}
2121
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002122void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002123 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002124}
2125
2126
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002127// ------------------------------------
2128// Cast operations
2129
2130
2131CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002132CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002133CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002134CAST_ACCESSOR(DeoptimizationInputData)
2135CAST_ACCESSOR(DeoptimizationOutputData)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002136CAST_ACCESSOR(TypeFeedbackCells)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002137CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002138CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002139CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002140CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002141CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002142CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002143CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002144CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002145CAST_ACCESSOR(String)
2146CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002147CAST_ACCESSOR(SeqAsciiString)
2148CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002149CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002150CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002151CAST_ACCESSOR(ExternalString)
2152CAST_ACCESSOR(ExternalAsciiString)
2153CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002154CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002155CAST_ACCESSOR(JSObject)
2156CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002157CAST_ACCESSOR(HeapObject)
2158CAST_ACCESSOR(HeapNumber)
2159CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002160CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002161CAST_ACCESSOR(SharedFunctionInfo)
2162CAST_ACCESSOR(Map)
2163CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002164CAST_ACCESSOR(GlobalObject)
2165CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002166CAST_ACCESSOR(JSGlobalObject)
2167CAST_ACCESSOR(JSBuiltinsObject)
2168CAST_ACCESSOR(Code)
2169CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002170CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002171CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002172CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002173CAST_ACCESSOR(JSSet)
2174CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002175CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002176CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002177CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002178CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002179CAST_ACCESSOR(ExternalArray)
2180CAST_ACCESSOR(ExternalByteArray)
2181CAST_ACCESSOR(ExternalUnsignedByteArray)
2182CAST_ACCESSOR(ExternalShortArray)
2183CAST_ACCESSOR(ExternalUnsignedShortArray)
2184CAST_ACCESSOR(ExternalIntArray)
2185CAST_ACCESSOR(ExternalUnsignedIntArray)
2186CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002187CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002188CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002189CAST_ACCESSOR(Struct)
2190
2191
2192#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2193 STRUCT_LIST(MAKE_STRUCT_CAST)
2194#undef MAKE_STRUCT_CAST
2195
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002196
2197template <typename Shape, typename Key>
2198HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002199 ASSERT(obj->IsHashTable());
2200 return reinterpret_cast<HashTable*>(obj);
2201}
2202
2203
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002204SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002205SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002206
ager@chromium.orgac091b72010-05-05 07:34:42 +00002207SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002208
2209
2210uint32_t String::hash_field() {
2211 return READ_UINT32_FIELD(this, kHashFieldOffset);
2212}
2213
2214
2215void String::set_hash_field(uint32_t value) {
2216 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002217#if V8_HOST_ARCH_64_BIT
2218 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2219#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002220}
2221
2222
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002223bool String::Equals(String* other) {
2224 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002225 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2226 return false;
2227 }
2228 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002229}
2230
2231
lrn@chromium.org303ada72010-10-27 09:33:13 +00002232MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002233 if (!StringShape(this).IsCons()) return this;
2234 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002235 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002236 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002237}
2238
2239
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002240String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002241 MaybeObject* flat = TryFlatten(pretenure);
2242 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002243 if (!flat->ToObject(&successfully_flattened)) return this;
2244 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002245}
2246
2247
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002248uint16_t String::Get(int index) {
2249 ASSERT(index >= 0 && index < length());
2250 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002251 case kSeqStringTag | kAsciiStringTag:
2252 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2253 case kSeqStringTag | kTwoByteStringTag:
2254 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2255 case kConsStringTag | kAsciiStringTag:
2256 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002257 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002258 case kExternalStringTag | kAsciiStringTag:
2259 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2260 case kExternalStringTag | kTwoByteStringTag:
2261 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002262 case kSlicedStringTag | kAsciiStringTag:
2263 case kSlicedStringTag | kTwoByteStringTag:
2264 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002265 default:
2266 break;
2267 }
2268
2269 UNREACHABLE();
2270 return 0;
2271}
2272
2273
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002274void String::Set(int index, uint16_t value) {
2275 ASSERT(index >= 0 && index < length());
2276 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002277
ager@chromium.org5ec48922009-05-05 07:25:34 +00002278 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002279 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2280 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002281}
2282
2283
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002284bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002285 if (!StringShape(this).IsCons()) return true;
2286 return ConsString::cast(this)->second()->length() == 0;
2287}
2288
2289
2290String* String::GetUnderlying() {
2291 // Giving direct access to underlying string only makes sense if the
2292 // wrapping string is already flattened.
2293 ASSERT(this->IsFlat());
2294 ASSERT(StringShape(this).IsIndirect());
2295 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2296 const int kUnderlyingOffset = SlicedString::kParentOffset;
2297 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002298}
2299
2300
ager@chromium.org7c537e22008-10-16 08:43:32 +00002301uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002302 ASSERT(index >= 0 && index < length());
2303 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2304}
2305
2306
ager@chromium.org7c537e22008-10-16 08:43:32 +00002307void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002308 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2309 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2310 static_cast<byte>(value));
2311}
2312
2313
ager@chromium.org7c537e22008-10-16 08:43:32 +00002314Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002315 return FIELD_ADDR(this, kHeaderSize);
2316}
2317
2318
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002319char* SeqAsciiString::GetChars() {
2320 return reinterpret_cast<char*>(GetCharsAddress());
2321}
2322
2323
ager@chromium.org7c537e22008-10-16 08:43:32 +00002324Address SeqTwoByteString::GetCharsAddress() {
2325 return FIELD_ADDR(this, kHeaderSize);
2326}
2327
2328
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002329uc16* SeqTwoByteString::GetChars() {
2330 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2331}
2332
2333
ager@chromium.org7c537e22008-10-16 08:43:32 +00002334uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002335 ASSERT(index >= 0 && index < length());
2336 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2337}
2338
2339
ager@chromium.org7c537e22008-10-16 08:43:32 +00002340void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002341 ASSERT(index >= 0 && index < length());
2342 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2343}
2344
2345
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002346int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002347 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002348}
2349
2350
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002351int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002352 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002353}
2354
2355
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002356String* SlicedString::parent() {
2357 return String::cast(READ_FIELD(this, kParentOffset));
2358}
2359
2360
2361void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002362 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002363 WRITE_FIELD(this, kParentOffset, parent);
2364}
2365
2366
2367SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2368
2369
ager@chromium.org870a0b62008-11-04 11:43:05 +00002370String* ConsString::first() {
2371 return String::cast(READ_FIELD(this, kFirstOffset));
2372}
2373
2374
2375Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002376 return READ_FIELD(this, kFirstOffset);
2377}
2378
2379
ager@chromium.org870a0b62008-11-04 11:43:05 +00002380void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002381 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002382 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002383}
2384
2385
ager@chromium.org870a0b62008-11-04 11:43:05 +00002386String* ConsString::second() {
2387 return String::cast(READ_FIELD(this, kSecondOffset));
2388}
2389
2390
2391Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002392 return READ_FIELD(this, kSecondOffset);
2393}
2394
2395
ager@chromium.org870a0b62008-11-04 11:43:05 +00002396void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002397 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002398 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002399}
2400
2401
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002402bool ExternalString::is_short() {
2403 InstanceType type = map()->instance_type();
2404 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002405}
2406
2407
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002408const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002409 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2410}
2411
2412
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002413void ExternalAsciiString::update_data_cache() {
2414 if (is_short()) return;
2415 const char** data_field =
2416 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2417 *data_field = resource()->data();
2418}
2419
2420
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002421void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002422 const ExternalAsciiString::Resource* resource) {
2423 *reinterpret_cast<const Resource**>(
2424 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002425 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002426}
2427
2428
2429const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002430 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002431}
2432
2433
2434uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2435 ASSERT(index >= 0 && index < length());
2436 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002437}
2438
2439
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002440const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002441 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2442}
2443
2444
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002445void ExternalTwoByteString::update_data_cache() {
2446 if (is_short()) return;
2447 const uint16_t** data_field =
2448 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2449 *data_field = resource()->data();
2450}
2451
2452
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002453void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002454 const ExternalTwoByteString::Resource* resource) {
2455 *reinterpret_cast<const Resource**>(
2456 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002457 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002458}
2459
2460
2461const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002462 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002463}
2464
2465
2466uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2467 ASSERT(index >= 0 && index < length());
2468 return GetChars()[index];
2469}
2470
2471
2472const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2473 unsigned start) {
2474 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002475}
2476
2477
ager@chromium.orgac091b72010-05-05 07:34:42 +00002478void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002479 set_finger_index(kEntriesIndex);
2480 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002481}
2482
2483
2484void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002485 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002486 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002487 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002488 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002489 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002490 MakeZeroSize();
2491}
2492
2493
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002494int JSFunctionResultCache::size() {
2495 return Smi::cast(get(kCacheSizeIndex))->value();
2496}
2497
2498
2499void JSFunctionResultCache::set_size(int size) {
2500 set(kCacheSizeIndex, Smi::FromInt(size));
2501}
2502
2503
2504int JSFunctionResultCache::finger_index() {
2505 return Smi::cast(get(kFingerIndex))->value();
2506}
2507
2508
2509void JSFunctionResultCache::set_finger_index(int finger_index) {
2510 set(kFingerIndex, Smi::FromInt(finger_index));
2511}
2512
2513
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002514byte ByteArray::get(int index) {
2515 ASSERT(index >= 0 && index < this->length());
2516 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2517}
2518
2519
2520void ByteArray::set(int index, byte value) {
2521 ASSERT(index >= 0 && index < this->length());
2522 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2523}
2524
2525
2526int ByteArray::get_int(int index) {
2527 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2528 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2529}
2530
2531
2532ByteArray* ByteArray::FromDataStartAddress(Address address) {
2533 ASSERT_TAG_ALIGNED(address);
2534 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2535}
2536
2537
2538Address ByteArray::GetDataStartAddress() {
2539 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2540}
2541
2542
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002543uint8_t* ExternalPixelArray::external_pixel_pointer() {
2544 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002545}
2546
2547
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002548uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002549 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002550 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002551 return ptr[index];
2552}
2553
2554
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002555MaybeObject* ExternalPixelArray::get(int index) {
2556 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2557}
2558
2559
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002560void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002561 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002562 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002563 ptr[index] = value;
2564}
2565
2566
ager@chromium.org3811b432009-10-28 14:53:37 +00002567void* ExternalArray::external_pointer() {
2568 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2569 return reinterpret_cast<void*>(ptr);
2570}
2571
2572
2573void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2574 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2575 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2576}
2577
2578
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002579int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002580 ASSERT((index >= 0) && (index < this->length()));
2581 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2582 return ptr[index];
2583}
2584
2585
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002586MaybeObject* ExternalByteArray::get(int index) {
2587 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2588}
2589
2590
ager@chromium.org3811b432009-10-28 14:53:37 +00002591void ExternalByteArray::set(int index, int8_t value) {
2592 ASSERT((index >= 0) && (index < this->length()));
2593 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2594 ptr[index] = value;
2595}
2596
2597
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002598uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002599 ASSERT((index >= 0) && (index < this->length()));
2600 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2601 return ptr[index];
2602}
2603
2604
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002605MaybeObject* ExternalUnsignedByteArray::get(int index) {
2606 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2607}
2608
2609
ager@chromium.org3811b432009-10-28 14:53:37 +00002610void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2611 ASSERT((index >= 0) && (index < this->length()));
2612 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2613 ptr[index] = value;
2614}
2615
2616
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002617int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002618 ASSERT((index >= 0) && (index < this->length()));
2619 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2620 return ptr[index];
2621}
2622
2623
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002624MaybeObject* ExternalShortArray::get(int index) {
2625 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2626}
2627
2628
ager@chromium.org3811b432009-10-28 14:53:37 +00002629void ExternalShortArray::set(int index, int16_t value) {
2630 ASSERT((index >= 0) && (index < this->length()));
2631 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2632 ptr[index] = value;
2633}
2634
2635
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002636uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002637 ASSERT((index >= 0) && (index < this->length()));
2638 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2639 return ptr[index];
2640}
2641
2642
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002643MaybeObject* ExternalUnsignedShortArray::get(int index) {
2644 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2645}
2646
2647
ager@chromium.org3811b432009-10-28 14:53:37 +00002648void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2649 ASSERT((index >= 0) && (index < this->length()));
2650 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2651 ptr[index] = value;
2652}
2653
2654
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002655int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002656 ASSERT((index >= 0) && (index < this->length()));
2657 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2658 return ptr[index];
2659}
2660
2661
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002662MaybeObject* ExternalIntArray::get(int index) {
2663 return GetHeap()->NumberFromInt32(get_scalar(index));
2664}
2665
2666
ager@chromium.org3811b432009-10-28 14:53:37 +00002667void ExternalIntArray::set(int index, int32_t value) {
2668 ASSERT((index >= 0) && (index < this->length()));
2669 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2670 ptr[index] = value;
2671}
2672
2673
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002674uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002675 ASSERT((index >= 0) && (index < this->length()));
2676 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2677 return ptr[index];
2678}
2679
2680
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002681MaybeObject* ExternalUnsignedIntArray::get(int index) {
2682 return GetHeap()->NumberFromUint32(get_scalar(index));
2683}
2684
2685
ager@chromium.org3811b432009-10-28 14:53:37 +00002686void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2687 ASSERT((index >= 0) && (index < this->length()));
2688 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2689 ptr[index] = value;
2690}
2691
2692
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002693float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002694 ASSERT((index >= 0) && (index < this->length()));
2695 float* ptr = static_cast<float*>(external_pointer());
2696 return ptr[index];
2697}
2698
2699
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002700MaybeObject* ExternalFloatArray::get(int index) {
2701 return GetHeap()->NumberFromDouble(get_scalar(index));
2702}
2703
2704
ager@chromium.org3811b432009-10-28 14:53:37 +00002705void ExternalFloatArray::set(int index, float value) {
2706 ASSERT((index >= 0) && (index < this->length()));
2707 float* ptr = static_cast<float*>(external_pointer());
2708 ptr[index] = value;
2709}
2710
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002711
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002712double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002713 ASSERT((index >= 0) && (index < this->length()));
2714 double* ptr = static_cast<double*>(external_pointer());
2715 return ptr[index];
2716}
2717
2718
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002719MaybeObject* ExternalDoubleArray::get(int index) {
2720 return GetHeap()->NumberFromDouble(get_scalar(index));
2721}
2722
2723
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002724void ExternalDoubleArray::set(int index, double value) {
2725 ASSERT((index >= 0) && (index < this->length()));
2726 double* ptr = static_cast<double*>(external_pointer());
2727 ptr[index] = value;
2728}
2729
2730
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002731int Map::visitor_id() {
2732 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2733}
2734
2735
2736void Map::set_visitor_id(int id) {
2737 ASSERT(0 <= id && id < 256);
2738 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2739}
2740
ager@chromium.org3811b432009-10-28 14:53:37 +00002741
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002742int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002743 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2744}
2745
2746
2747int Map::inobject_properties() {
2748 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002749}
2750
2751
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002752int Map::pre_allocated_property_fields() {
2753 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2754}
2755
2756
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002757int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002758 int instance_size = map->instance_size();
2759 if (instance_size != kVariableSizeSentinel) return instance_size;
2760 // We can ignore the "symbol" bit becase it is only set for symbols
2761 // and implies a string type.
2762 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002763 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002764 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002765 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002766 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002767 if (instance_type == ASCII_STRING_TYPE) {
2768 return SeqAsciiString::SizeFor(
2769 reinterpret_cast<SeqAsciiString*>(this)->length());
2770 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002771 if (instance_type == BYTE_ARRAY_TYPE) {
2772 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2773 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002774 if (instance_type == FREE_SPACE_TYPE) {
2775 return reinterpret_cast<FreeSpace*>(this)->size();
2776 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002777 if (instance_type == STRING_TYPE) {
2778 return SeqTwoByteString::SizeFor(
2779 reinterpret_cast<SeqTwoByteString*>(this)->length());
2780 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002781 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2782 return FixedDoubleArray::SizeFor(
2783 reinterpret_cast<FixedDoubleArray*>(this)->length());
2784 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002785 ASSERT(instance_type == CODE_TYPE);
2786 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002787}
2788
2789
2790void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002791 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002792 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002793 ASSERT(0 <= value && value < 256);
2794 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2795}
2796
2797
ager@chromium.org7c537e22008-10-16 08:43:32 +00002798void Map::set_inobject_properties(int value) {
2799 ASSERT(0 <= value && value < 256);
2800 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2801}
2802
2803
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002804void Map::set_pre_allocated_property_fields(int value) {
2805 ASSERT(0 <= value && value < 256);
2806 WRITE_BYTE_FIELD(this,
2807 kPreAllocatedPropertyFieldsOffset,
2808 static_cast<byte>(value));
2809}
2810
2811
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002812InstanceType Map::instance_type() {
2813 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2814}
2815
2816
2817void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002818 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2819}
2820
2821
2822int Map::unused_property_fields() {
2823 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2824}
2825
2826
2827void Map::set_unused_property_fields(int value) {
2828 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2829}
2830
2831
2832byte Map::bit_field() {
2833 return READ_BYTE_FIELD(this, kBitFieldOffset);
2834}
2835
2836
2837void Map::set_bit_field(byte value) {
2838 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2839}
2840
2841
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002842byte Map::bit_field2() {
2843 return READ_BYTE_FIELD(this, kBitField2Offset);
2844}
2845
2846
2847void Map::set_bit_field2(byte value) {
2848 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2849}
2850
2851
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002852void Map::set_non_instance_prototype(bool value) {
2853 if (value) {
2854 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2855 } else {
2856 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2857 }
2858}
2859
2860
2861bool Map::has_non_instance_prototype() {
2862 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2863}
2864
2865
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002866void Map::set_function_with_prototype(bool value) {
2867 if (value) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002868 set_bit_field3(bit_field3() | (1 << kFunctionWithPrototype));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002869 } else {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002870 set_bit_field3(bit_field3() & ~(1 << kFunctionWithPrototype));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002871 }
2872}
2873
2874
2875bool Map::function_with_prototype() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002876 return ((1 << kFunctionWithPrototype) & bit_field3()) != 0;
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002877}
2878
2879
ager@chromium.org870a0b62008-11-04 11:43:05 +00002880void Map::set_is_access_check_needed(bool access_check_needed) {
2881 if (access_check_needed) {
2882 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2883 } else {
2884 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2885 }
2886}
2887
2888
2889bool Map::is_access_check_needed() {
2890 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2891}
2892
2893
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002894void Map::set_is_extensible(bool value) {
2895 if (value) {
2896 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2897 } else {
2898 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2899 }
2900}
2901
2902bool Map::is_extensible() {
2903 return ((1 << kIsExtensible) & bit_field2()) != 0;
2904}
2905
2906
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002907void Map::set_attached_to_shared_function_info(bool value) {
2908 if (value) {
2909 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2910 } else {
2911 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2912 }
2913}
2914
2915bool Map::attached_to_shared_function_info() {
2916 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2917}
2918
2919
2920void Map::set_is_shared(bool value) {
2921 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002922 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002923 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002924 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002925 }
2926}
2927
2928bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002929 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002930}
2931
2932
2933JSFunction* Map::unchecked_constructor() {
2934 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2935}
2936
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002937
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002938Code::Flags Code::flags() {
2939 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2940}
2941
2942
2943void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002944 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002945 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002946 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2947 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002948 ExtractArgumentsCountFromFlags(flags) >= 0);
2949 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2950}
2951
2952
2953Code::Kind Code::kind() {
2954 return ExtractKindFromFlags(flags());
2955}
2956
2957
kasper.lund7276f142008-07-30 08:49:36 +00002958InlineCacheState Code::ic_state() {
2959 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002960 // Only allow uninitialized or debugger states for non-IC code
2961 // objects. This is used in the debugger to determine whether or not
2962 // a call to code object has been replaced with a debug break call.
2963 ASSERT(is_inline_cache_stub() ||
2964 result == UNINITIALIZED ||
2965 result == DEBUG_BREAK ||
2966 result == DEBUG_PREPARE_STEP_IN);
2967 return result;
2968}
2969
2970
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002971Code::ExtraICState Code::extra_ic_state() {
2972 ASSERT(is_inline_cache_stub());
2973 return ExtractExtraICStateFromFlags(flags());
2974}
2975
2976
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002977PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002978 return ExtractTypeFromFlags(flags());
2979}
2980
2981
2982int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002983 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002984 return ExtractArgumentsCountFromFlags(flags());
2985}
2986
2987
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002988int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002989 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002990 kind() == UNARY_OP_IC ||
2991 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002992 kind() == COMPARE_IC ||
2993 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002994 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002995}
2996
2997
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002998void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002999 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003000 kind() == UNARY_OP_IC ||
3001 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003002 kind() == COMPARE_IC ||
3003 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00003004 ASSERT(0 <= major && major < 256);
3005 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003006}
3007
3008
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003009bool Code::is_pregenerated() {
3010 return kind() == STUB && IsPregeneratedField::decode(flags());
3011}
3012
3013
3014void Code::set_is_pregenerated(bool value) {
3015 ASSERT(kind() == STUB);
3016 Flags f = flags();
3017 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3018 set_flags(f);
3019}
3020
3021
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003022bool Code::optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003023 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003024 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3025}
3026
3027
3028void Code::set_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003029 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003030 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3031}
3032
3033
3034bool Code::has_deoptimization_support() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003035 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003036 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3037 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003038}
3039
3040
3041void Code::set_has_deoptimization_support(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003042 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003043 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3044 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3045 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3046}
3047
3048
3049bool Code::has_debug_break_slots() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003050 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003051 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3052 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3053}
3054
3055
3056void Code::set_has_debug_break_slots(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003057 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003058 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3059 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3060 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003061}
3062
3063
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003064bool Code::is_compiled_optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003065 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003066 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3067 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3068}
3069
3070
3071void Code::set_compiled_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003072 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003073 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3074 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3075 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3076}
3077
3078
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003079int Code::allow_osr_at_loop_nesting_level() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003080 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003081 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3082}
3083
3084
3085void Code::set_allow_osr_at_loop_nesting_level(int level) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003086 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003087 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3088 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3089}
3090
3091
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003092int Code::profiler_ticks() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003093 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003094 return READ_BYTE_FIELD(this, kProfilerTicksOffset);
3095}
3096
3097
3098void Code::set_profiler_ticks(int ticks) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003099 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003100 ASSERT(ticks < 256);
3101 WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
3102}
3103
3104
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003105unsigned Code::stack_slots() {
3106 ASSERT(kind() == OPTIMIZED_FUNCTION);
3107 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3108}
3109
3110
3111void Code::set_stack_slots(unsigned slots) {
3112 ASSERT(kind() == OPTIMIZED_FUNCTION);
3113 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3114}
3115
3116
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003117unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003118 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003119 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003120}
3121
3122
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003123void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003124 ASSERT(kind() == OPTIMIZED_FUNCTION);
3125 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003126 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003127}
3128
3129
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003130unsigned Code::stack_check_table_offset() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003131 ASSERT_EQ(FUNCTION, kind());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003132 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003133}
3134
3135
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003136void Code::set_stack_check_table_offset(unsigned offset) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003137 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003138 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003139 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003140}
3141
3142
3143CheckType Code::check_type() {
3144 ASSERT(is_call_stub() || is_keyed_call_stub());
3145 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3146 return static_cast<CheckType>(type);
3147}
3148
3149
3150void Code::set_check_type(CheckType value) {
3151 ASSERT(is_call_stub() || is_keyed_call_stub());
3152 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3153}
3154
3155
danno@chromium.org40cb8782011-05-25 07:58:50 +00003156byte Code::unary_op_type() {
3157 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003158 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3159}
3160
3161
danno@chromium.org40cb8782011-05-25 07:58:50 +00003162void Code::set_unary_op_type(byte value) {
3163 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003164 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3165}
3166
3167
danno@chromium.org40cb8782011-05-25 07:58:50 +00003168byte Code::binary_op_type() {
3169 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003170 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3171}
3172
3173
danno@chromium.org40cb8782011-05-25 07:58:50 +00003174void Code::set_binary_op_type(byte value) {
3175 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003176 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3177}
3178
3179
danno@chromium.org40cb8782011-05-25 07:58:50 +00003180byte Code::binary_op_result_type() {
3181 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003182 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3183}
3184
3185
danno@chromium.org40cb8782011-05-25 07:58:50 +00003186void Code::set_binary_op_result_type(byte value) {
3187 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003188 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3189}
3190
3191
3192byte Code::compare_state() {
3193 ASSERT(is_compare_ic_stub());
3194 return READ_BYTE_FIELD(this, kCompareStateOffset);
3195}
3196
3197
3198void Code::set_compare_state(byte value) {
3199 ASSERT(is_compare_ic_stub());
3200 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3201}
3202
3203
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003204byte Code::compare_operation() {
3205 ASSERT(is_compare_ic_stub());
3206 return READ_BYTE_FIELD(this, kCompareOperationOffset);
3207}
3208
3209
3210void Code::set_compare_operation(byte value) {
3211 ASSERT(is_compare_ic_stub());
3212 WRITE_BYTE_FIELD(this, kCompareOperationOffset, value);
3213}
3214
3215
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003216byte Code::to_boolean_state() {
3217 ASSERT(is_to_boolean_ic_stub());
3218 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3219}
3220
3221
3222void Code::set_to_boolean_state(byte value) {
3223 ASSERT(is_to_boolean_ic_stub());
3224 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3225}
3226
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003227
3228bool Code::has_function_cache() {
3229 ASSERT(kind() == STUB);
3230 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3231}
3232
3233
3234void Code::set_has_function_cache(bool flag) {
3235 ASSERT(kind() == STUB);
3236 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3237}
3238
3239
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003240bool Code::is_inline_cache_stub() {
3241 Kind kind = this->kind();
3242 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3243}
3244
3245
3246Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003247 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003248 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003249 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003250 int argc,
3251 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003252 // Extra IC state is only allowed for call IC stubs or for store IC
3253 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003254 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003255 kind == CALL_IC ||
3256 kind == STORE_IC ||
3257 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003258 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003259 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003260 | ICStateField::encode(ic_state)
3261 | TypeField::encode(type)
3262 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003263 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003264 | CacheHolderField::encode(holder);
3265 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003266}
3267
3268
3269Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3270 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003271 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003272 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003273 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003274 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003275}
3276
3277
3278Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003279 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003280}
3281
3282
kasper.lund7276f142008-07-30 08:49:36 +00003283InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003284 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003285}
3286
3287
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003288Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003289 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003290}
3291
3292
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003293PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003294 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003295}
3296
3297
3298int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003299 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003300}
3301
3302
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003303InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003304 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003305}
3306
3307
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003308Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003309 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003310 return static_cast<Flags>(bits);
3311}
3312
3313
ager@chromium.org8bb60582008-12-11 12:02:20 +00003314Code* Code::GetCodeFromTargetAddress(Address address) {
3315 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3316 // GetCodeFromTargetAddress might be called when marking objects during mark
3317 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3318 // Code::cast. Code::cast does not work when the object's map is
3319 // marked.
3320 Code* result = reinterpret_cast<Code*>(code);
3321 return result;
3322}
3323
3324
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003325Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3326 return HeapObject::
3327 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3328}
3329
3330
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003331Object* Map::prototype() {
3332 return READ_FIELD(this, kPrototypeOffset);
3333}
3334
3335
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003336void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003337 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003338 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003339 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003340}
3341
3342
danno@chromium.org40cb8782011-05-25 07:58:50 +00003343DescriptorArray* Map::instance_descriptors() {
3344 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3345 if (object->IsSmi()) {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003346 return GetHeap()->empty_descriptor_array();
danno@chromium.org40cb8782011-05-25 07:58:50 +00003347 } else {
3348 return DescriptorArray::cast(object);
3349 }
3350}
3351
3352
3353void Map::init_instance_descriptors() {
3354 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3355}
3356
3357
3358void Map::clear_instance_descriptors() {
3359 Object* object = READ_FIELD(this,
3360 kInstanceDescriptorsOrBitField3Offset);
3361 if (!object->IsSmi()) {
yangguo@chromium.org5f0b8ea2012-05-16 12:37:04 +00003362#ifdef DEBUG
3363 ZapInstanceDescriptors();
3364#endif
danno@chromium.org40cb8782011-05-25 07:58:50 +00003365 WRITE_FIELD(
3366 this,
3367 kInstanceDescriptorsOrBitField3Offset,
3368 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3369 }
3370}
3371
3372
3373void Map::set_instance_descriptors(DescriptorArray* value,
3374 WriteBarrierMode mode) {
3375 Object* object = READ_FIELD(this,
3376 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003377 Heap* heap = GetHeap();
3378 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003379 clear_instance_descriptors();
3380 return;
3381 } else {
3382 if (object->IsSmi()) {
3383 value->set_bit_field3_storage(Smi::cast(object)->value());
3384 } else {
3385 value->set_bit_field3_storage(
3386 DescriptorArray::cast(object)->bit_field3_storage());
3387 }
3388 }
3389 ASSERT(!is_shared());
yangguo@chromium.org5f0b8ea2012-05-16 12:37:04 +00003390#ifdef DEBUG
3391 if (value != instance_descriptors()) {
3392 ZapInstanceDescriptors();
3393 }
3394#endif
danno@chromium.org40cb8782011-05-25 07:58:50 +00003395 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003396 CONDITIONAL_WRITE_BARRIER(
3397 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003398}
3399
3400
3401int Map::bit_field3() {
3402 Object* object = READ_FIELD(this,
3403 kInstanceDescriptorsOrBitField3Offset);
3404 if (object->IsSmi()) {
3405 return Smi::cast(object)->value();
3406 } else {
3407 return DescriptorArray::cast(object)->bit_field3_storage();
3408 }
3409}
3410
3411
3412void Map::set_bit_field3(int value) {
3413 ASSERT(Smi::IsValid(value));
3414 Object* object = READ_FIELD(this,
3415 kInstanceDescriptorsOrBitField3Offset);
3416 if (object->IsSmi()) {
3417 WRITE_FIELD(this,
3418 kInstanceDescriptorsOrBitField3Offset,
3419 Smi::FromInt(value));
3420 } else {
3421 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3422 }
3423}
3424
3425
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003426Object* Map::GetBackPointer() {
3427 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3428 if (object->IsFixedArray()) {
3429 return FixedArray::cast(object)->get(kProtoTransitionBackPointerOffset);
3430 } else {
3431 return object;
3432 }
3433}
3434
3435
3436void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
3437 Heap* heap = GetHeap();
3438 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
3439 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
3440 (value->IsMap() && GetBackPointer()->IsUndefined()));
3441 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3442 if (object->IsFixedArray()) {
3443 FixedArray::cast(object)->set(
3444 kProtoTransitionBackPointerOffset, value, mode);
3445 } else {
3446 WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
3447 CONDITIONAL_WRITE_BARRIER(
3448 heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
3449 }
3450}
3451
3452
3453FixedArray* Map::prototype_transitions() {
3454 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3455 if (object->IsFixedArray()) {
3456 return FixedArray::cast(object);
3457 } else {
3458 return GetHeap()->empty_fixed_array();
3459 }
3460}
3461
3462
3463void Map::set_prototype_transitions(FixedArray* value, WriteBarrierMode mode) {
3464 Heap* heap = GetHeap();
3465 ASSERT(value != heap->empty_fixed_array());
3466 value->set(kProtoTransitionBackPointerOffset, GetBackPointer());
yangguo@chromium.org5f0b8ea2012-05-16 12:37:04 +00003467#ifdef DEBUG
3468 if (value != prototype_transitions()) {
3469 ZapPrototypeTransitions();
3470 }
3471#endif
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003472 WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
3473 CONDITIONAL_WRITE_BARRIER(
3474 heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
3475}
3476
3477
3478void Map::init_prototype_transitions(Object* undefined) {
3479 ASSERT(undefined->IsUndefined());
3480 WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, undefined);
3481}
3482
3483
3484HeapObject* Map::unchecked_prototype_transitions() {
3485 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3486 return reinterpret_cast<HeapObject*>(object);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003487}
3488
3489
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003490ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003491ACCESSORS(Map, constructor, Object, kConstructorOffset)
3492
3493ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003494ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003495ACCESSORS(JSFunction,
3496 next_function_link,
3497 Object,
3498 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003499
3500ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3501ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003502ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003503
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003504ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003505
3506ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3507ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3508ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3509ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003510ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003511
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003512ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3513ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3514
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003515ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3516ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3517ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3518
3519ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3520ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3521ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3522ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3523ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3524ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3525
3526ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3527ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3528
3529ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3530ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3531
3532ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3533ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003534ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3535 kPropertyAccessorsOffset)
3536ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3537 kPrototypeTemplateOffset)
3538ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3539ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3540 kNamedPropertyHandlerOffset)
3541ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3542 kIndexedPropertyHandlerOffset)
3543ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3544 kInstanceTemplateOffset)
3545ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3546ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003547ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3548 kInstanceCallHandlerOffset)
3549ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3550 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003551ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003552
3553ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003554ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3555 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003556
3557ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3558ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3559
3560ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3561
3562ACCESSORS(Script, source, Object, kSourceOffset)
3563ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003564ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003565ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
3566ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003567ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003568ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003569ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003570ACCESSORS_TO_SMI(Script, type, kTypeOffset)
3571ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
3572ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003573ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003574ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003575ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
3576 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003577
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003578#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003579ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3580ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3581ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3582ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3583
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003584ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
3585ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
3586ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003587ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003588#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003589
3590ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003591ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3592ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003593ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3594 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003595ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003596ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3597ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003598ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003599ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3600 kThisPropertyAssignmentsOffset)
danno@chromium.org1044a4d2012-04-30 12:34:39 +00003601SMI_ACCESSORS(SharedFunctionInfo, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003602
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00003603
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003604BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3605 kHiddenPrototypeBit)
3606BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3607BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3608 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003609BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3610 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003611BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3612 kIsExpressionBit)
3613BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3614 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003615BOOL_GETTER(SharedFunctionInfo,
3616 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003617 has_only_simple_this_property_assignments,
3618 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003619BOOL_ACCESSORS(SharedFunctionInfo,
3620 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003621 allows_lazy_compilation,
3622 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003623BOOL_ACCESSORS(SharedFunctionInfo,
3624 compiler_hints,
3625 uses_arguments,
3626 kUsesArguments)
3627BOOL_ACCESSORS(SharedFunctionInfo,
3628 compiler_hints,
3629 has_duplicate_parameters,
3630 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003631
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003632
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003633#if V8_HOST_ARCH_32_BIT
3634SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3635SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003636 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003637SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003638 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003639SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3640SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003641 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003642SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3643SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003644 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003645SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003646 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003647SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003648 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003649SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003650SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3651SMI_ACCESSORS(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003652#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003653
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003654#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003655 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003656 int holder::name() { \
3657 int value = READ_INT_FIELD(this, offset); \
3658 ASSERT(kHeapObjectTag == 1); \
3659 ASSERT((value & kHeapObjectTag) == 0); \
3660 return value >> 1; \
3661 } \
3662 void holder::set_##name(int value) { \
3663 ASSERT(kHeapObjectTag == 1); \
3664 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3665 (value & 0xC0000000) == 0x000000000); \
3666 WRITE_INT_FIELD(this, \
3667 offset, \
3668 (value << 1) & ~kHeapObjectTag); \
3669 }
3670
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003671#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3672 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003673 INT_ACCESSORS(holder, name, offset)
3674
3675
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003676PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003677PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3678 formal_parameter_count,
3679 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003680
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003681PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3682 expected_nof_properties,
3683 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003684PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3685
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003686PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3687PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3688 start_position_and_type,
3689 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003690
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003691PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3692 function_token_position,
3693 kFunctionTokenPositionOffset)
3694PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3695 compiler_hints,
3696 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003697
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003698PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3699 this_property_assignments_count,
3700 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003701PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003702
3703PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3704PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003705#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003706
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003707
3708int SharedFunctionInfo::construction_count() {
3709 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3710}
3711
3712
3713void SharedFunctionInfo::set_construction_count(int value) {
3714 ASSERT(0 <= value && value < 256);
3715 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3716}
3717
3718
whesse@chromium.org7b260152011-06-20 15:33:18 +00003719BOOL_ACCESSORS(SharedFunctionInfo,
3720 compiler_hints,
3721 live_objects_may_exist,
3722 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003723
3724
3725bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003726 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003727}
3728
3729
whesse@chromium.org7b260152011-06-20 15:33:18 +00003730BOOL_GETTER(SharedFunctionInfo,
3731 compiler_hints,
3732 optimization_disabled,
3733 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003734
3735
3736void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3737 set_compiler_hints(BooleanBit::set(compiler_hints(),
3738 kOptimizationDisabled,
3739 disable));
3740 // If disabling optimizations we reflect that in the code object so
3741 // it will not be counted as optimizable code.
3742 if ((code()->kind() == Code::FUNCTION) && disable) {
3743 code()->set_optimizable(false);
3744 }
3745}
3746
3747
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003748int SharedFunctionInfo::profiler_ticks() {
3749 if (code()->kind() != Code::FUNCTION) return 0;
3750 return code()->profiler_ticks();
3751}
3752
3753
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003754LanguageMode SharedFunctionInfo::language_mode() {
3755 int hints = compiler_hints();
3756 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3757 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3758 return EXTENDED_MODE;
3759 }
3760 return BooleanBit::get(hints, kStrictModeFunction)
3761 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003762}
3763
3764
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003765void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3766 // We only allow language mode transitions that go set the same language mode
3767 // again or go up in the chain:
3768 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3769 ASSERT(this->language_mode() == CLASSIC_MODE ||
3770 this->language_mode() == language_mode ||
3771 language_mode == EXTENDED_MODE);
3772 int hints = compiler_hints();
3773 hints = BooleanBit::set(
3774 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3775 hints = BooleanBit::set(
3776 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3777 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003778}
3779
3780
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003781bool SharedFunctionInfo::is_classic_mode() {
3782 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3783}
3784
3785BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3786 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003787BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3788BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3789 name_should_print_as_anonymous,
3790 kNameShouldPrintAsAnonymous)
3791BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3792BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00003793BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
3794BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
3795 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003796BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003797
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003798ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3799ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3800
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003801ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3802
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003803bool Script::HasValidSource() {
3804 Object* src = this->source();
3805 if (!src->IsString()) return true;
3806 String* src_str = String::cast(src);
3807 if (!StringShape(src_str).IsExternal()) return true;
3808 if (src_str->IsAsciiRepresentation()) {
3809 return ExternalAsciiString::cast(src)->resource() != NULL;
3810 } else if (src_str->IsTwoByteRepresentation()) {
3811 return ExternalTwoByteString::cast(src)->resource() != NULL;
3812 }
3813 return true;
3814}
3815
3816
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003817void SharedFunctionInfo::DontAdaptArguments() {
3818 ASSERT(code()->kind() == Code::BUILTIN);
3819 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3820}
3821
3822
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003823int SharedFunctionInfo::start_position() {
3824 return start_position_and_type() >> kStartPositionShift;
3825}
3826
3827
3828void SharedFunctionInfo::set_start_position(int start_position) {
3829 set_start_position_and_type((start_position << kStartPositionShift)
3830 | (start_position_and_type() & ~kStartPositionMask));
3831}
3832
3833
3834Code* SharedFunctionInfo::code() {
3835 return Code::cast(READ_FIELD(this, kCodeOffset));
3836}
3837
3838
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003839Code* SharedFunctionInfo::unchecked_code() {
3840 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3841}
3842
3843
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003844void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003845 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003846 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003847}
3848
3849
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003850ScopeInfo* SharedFunctionInfo::scope_info() {
3851 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003852}
3853
3854
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003855void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003856 WriteBarrierMode mode) {
3857 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003858 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3859 this,
3860 kScopeInfoOffset,
3861 reinterpret_cast<Object*>(value),
3862 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003863}
3864
3865
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003866bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003867 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003868 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003869}
3870
3871
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003872bool SharedFunctionInfo::IsApiFunction() {
3873 return function_data()->IsFunctionTemplateInfo();
3874}
3875
3876
3877FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3878 ASSERT(IsApiFunction());
3879 return FunctionTemplateInfo::cast(function_data());
3880}
3881
3882
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003883bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003884 return function_data()->IsSmi();
3885}
3886
3887
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003888BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3889 ASSERT(HasBuiltinFunctionId());
3890 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003891}
3892
3893
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003894int SharedFunctionInfo::code_age() {
3895 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3896}
3897
3898
3899void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00003900 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3901 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003902}
3903
3904
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003905bool SharedFunctionInfo::has_deoptimization_support() {
3906 Code* code = this->code();
3907 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3908}
3909
3910
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003911bool JSFunction::IsBuiltin() {
3912 return context()->global()->IsJSBuiltinsObject();
3913}
3914
3915
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003916bool JSFunction::NeedsArgumentsAdaption() {
3917 return shared()->formal_parameter_count() !=
3918 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3919}
3920
3921
3922bool JSFunction::IsOptimized() {
3923 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3924}
3925
3926
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003927bool JSFunction::IsOptimizable() {
3928 return code()->kind() == Code::FUNCTION && code()->optimizable();
3929}
3930
3931
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003932bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003933 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003934}
3935
3936
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003937Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003938 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003939}
3940
3941
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003942Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003943 return reinterpret_cast<Code*>(
3944 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003945}
3946
3947
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003948void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003949 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003950 Address entry = value->entry();
3951 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003952 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3953 this,
3954 HeapObject::RawField(this, kCodeEntryOffset),
3955 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003956}
3957
3958
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003959void JSFunction::ReplaceCode(Code* code) {
3960 bool was_optimized = IsOptimized();
3961 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3962
3963 set_code(code);
3964
3965 // Add/remove the function from the list of optimized functions for this
3966 // context based on the state change.
3967 if (!was_optimized && is_optimized) {
3968 context()->global_context()->AddOptimizedFunction(this);
3969 }
3970 if (was_optimized && !is_optimized) {
3971 context()->global_context()->RemoveOptimizedFunction(this);
3972 }
3973}
3974
3975
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003976Context* JSFunction::context() {
3977 return Context::cast(READ_FIELD(this, kContextOffset));
3978}
3979
3980
3981Object* JSFunction::unchecked_context() {
3982 return READ_FIELD(this, kContextOffset);
3983}
3984
3985
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003986SharedFunctionInfo* JSFunction::unchecked_shared() {
3987 return reinterpret_cast<SharedFunctionInfo*>(
3988 READ_FIELD(this, kSharedFunctionInfoOffset));
3989}
3990
3991
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003992void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003993 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003994 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003995 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003996}
3997
3998ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3999 kPrototypeOrInitialMapOffset)
4000
4001
4002Map* JSFunction::initial_map() {
4003 return Map::cast(prototype_or_initial_map());
4004}
4005
4006
4007void JSFunction::set_initial_map(Map* value) {
4008 set_prototype_or_initial_map(value);
4009}
4010
4011
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004012MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
4013 Map* initial_map) {
4014 Context* global_context = context()->global_context();
4015 Object* array_function =
4016 global_context->get(Context::ARRAY_FUNCTION_INDEX);
4017 if (array_function->IsJSFunction() &&
4018 this == JSFunction::cast(array_function)) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004019 // Replace all of the cached initial array maps in the global context with
4020 // the appropriate transitioned elements kind maps.
4021 Heap* heap = GetHeap();
4022 MaybeObject* maybe_maps =
4023 heap->AllocateFixedArrayWithHoles(kElementsKindCount);
4024 FixedArray* maps;
4025 if (!maybe_maps->To(&maps)) return maybe_maps;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004026
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004027 Map* current_map = initial_map;
4028 ElementsKind kind = current_map->elements_kind();
4029 ASSERT(kind == GetInitialFastElementsKind());
4030 maps->set(kind, current_map);
4031 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
4032 i < kFastElementsKindCount; ++i) {
4033 ElementsKind transitioned_kind = GetFastElementsKindFromSequenceIndex(i);
4034 MaybeObject* maybe_new_map = current_map->CopyDropTransitions();
4035 Map* new_map = NULL;
4036 if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map;
4037 new_map->set_elements_kind(transitioned_kind);
4038 maybe_new_map = current_map->AddElementsTransition(transitioned_kind,
4039 new_map);
4040 if (maybe_new_map->IsFailure()) return maybe_new_map;
4041 maps->set(transitioned_kind, new_map);
4042 current_map = new_map;
4043 }
4044 global_context->set_js_array_maps(maps);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004045 }
4046 set_initial_map(initial_map);
4047 return this;
4048}
4049
4050
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004051bool JSFunction::has_initial_map() {
4052 return prototype_or_initial_map()->IsMap();
4053}
4054
4055
4056bool JSFunction::has_instance_prototype() {
4057 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4058}
4059
4060
4061bool JSFunction::has_prototype() {
4062 return map()->has_non_instance_prototype() || has_instance_prototype();
4063}
4064
4065
4066Object* JSFunction::instance_prototype() {
4067 ASSERT(has_instance_prototype());
4068 if (has_initial_map()) return initial_map()->prototype();
4069 // When there is no initial map and the prototype is a JSObject, the
4070 // initial map field is used for the prototype field.
4071 return prototype_or_initial_map();
4072}
4073
4074
4075Object* JSFunction::prototype() {
4076 ASSERT(has_prototype());
4077 // If the function's prototype property has been set to a non-JSObject
4078 // value, that value is stored in the constructor field of the map.
4079 if (map()->has_non_instance_prototype()) return map()->constructor();
4080 return instance_prototype();
4081}
4082
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00004083bool JSFunction::should_have_prototype() {
4084 return map()->function_with_prototype();
4085}
4086
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004087
4088bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004089 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004090}
4091
4092
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004093FixedArray* JSFunction::literals() {
4094 ASSERT(!shared()->bound());
4095 return literals_or_bindings();
4096}
4097
4098
4099void JSFunction::set_literals(FixedArray* literals) {
4100 ASSERT(!shared()->bound());
4101 set_literals_or_bindings(literals);
4102}
4103
4104
4105FixedArray* JSFunction::function_bindings() {
4106 ASSERT(shared()->bound());
4107 return literals_or_bindings();
4108}
4109
4110
4111void JSFunction::set_function_bindings(FixedArray* bindings) {
4112 ASSERT(shared()->bound());
4113 // Bound function literal may be initialized to the empty fixed array
4114 // before the bindings are set.
4115 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4116 bindings->map() == GetHeap()->fixed_cow_array_map());
4117 set_literals_or_bindings(bindings);
4118}
4119
4120
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004121int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004122 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004123 return literals()->length();
4124}
4125
4126
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004127Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004128 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004129 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004130}
4131
4132
4133void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4134 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004135 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004136 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004137 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004138}
4139
4140
4141Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004142 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004143 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4144}
4145
4146
4147void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4148 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004149 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004150 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004151 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004152}
4153
4154
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004155ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004156ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004157ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4158ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4159
4160
4161void JSProxy::InitializeBody(int object_size, Object* value) {
4162 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4163 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4164 WRITE_FIELD(this, offset, value);
4165 }
4166}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004167
4168
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004169ACCESSORS(JSSet, table, Object, kTableOffset)
4170ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004171ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4172ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004173
4174
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004175Address Foreign::foreign_address() {
4176 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004177}
4178
4179
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004180void Foreign::set_foreign_address(Address value) {
4181 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004182}
4183
4184
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004185ACCESSORS(JSModule, context, Object, kContextOffset)
4186
4187
4188JSModule* JSModule::cast(Object* obj) {
4189 ASSERT(obj->IsJSModule());
4190 ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
4191 return reinterpret_cast<JSModule*>(obj);
4192}
4193
4194
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004195ACCESSORS(JSValue, value, Object, kValueOffset)
4196
4197
4198JSValue* JSValue::cast(Object* obj) {
4199 ASSERT(obj->IsJSValue());
4200 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4201 return reinterpret_cast<JSValue*>(obj);
4202}
4203
4204
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004205ACCESSORS(JSDate, value, Object, kValueOffset)
4206ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4207ACCESSORS(JSDate, year, Object, kYearOffset)
4208ACCESSORS(JSDate, month, Object, kMonthOffset)
4209ACCESSORS(JSDate, day, Object, kDayOffset)
4210ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4211ACCESSORS(JSDate, hour, Object, kHourOffset)
4212ACCESSORS(JSDate, min, Object, kMinOffset)
4213ACCESSORS(JSDate, sec, Object, kSecOffset)
4214
4215
4216JSDate* JSDate::cast(Object* obj) {
4217 ASSERT(obj->IsJSDate());
4218 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4219 return reinterpret_cast<JSDate*>(obj);
4220}
4221
4222
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004223ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4224ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4225ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4226ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4227ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4228SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4229SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4230
4231
4232JSMessageObject* JSMessageObject::cast(Object* obj) {
4233 ASSERT(obj->IsJSMessageObject());
4234 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4235 return reinterpret_cast<JSMessageObject*>(obj);
4236}
4237
4238
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004239INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004240ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004241ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004242ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004243ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004244ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00004245INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004246
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004247byte* Code::instruction_start() {
4248 return FIELD_ADDR(this, kHeaderSize);
4249}
4250
4251
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004252byte* Code::instruction_end() {
4253 return instruction_start() + instruction_size();
4254}
4255
4256
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004257int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004258 return RoundUp(instruction_size(), kObjectAlignment);
4259}
4260
4261
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004262FixedArray* Code::unchecked_deoptimization_data() {
4263 return reinterpret_cast<FixedArray*>(
4264 READ_FIELD(this, kDeoptimizationDataOffset));
4265}
4266
4267
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004268ByteArray* Code::unchecked_relocation_info() {
4269 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004270}
4271
4272
4273byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004274 return unchecked_relocation_info()->GetDataStartAddress();
4275}
4276
4277
4278int Code::relocation_size() {
4279 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004280}
4281
4282
4283byte* Code::entry() {
4284 return instruction_start();
4285}
4286
4287
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004288bool Code::contains(byte* inner_pointer) {
4289 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004290}
4291
4292
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004293ACCESSORS(JSArray, length, Object, kLengthOffset)
4294
4295
ager@chromium.org236ad962008-09-25 09:45:57 +00004296ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004297
4298
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004299JSRegExp::Type JSRegExp::TypeTag() {
4300 Object* data = this->data();
4301 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4302 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4303 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004304}
4305
4306
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004307JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4308 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4309 return static_cast<JSRegExp::Type>(smi->value());
4310}
4311
4312
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004313int JSRegExp::CaptureCount() {
4314 switch (TypeTag()) {
4315 case ATOM:
4316 return 0;
4317 case IRREGEXP:
4318 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4319 default:
4320 UNREACHABLE();
4321 return -1;
4322 }
4323}
4324
4325
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004326JSRegExp::Flags JSRegExp::GetFlags() {
4327 ASSERT(this->data()->IsFixedArray());
4328 Object* data = this->data();
4329 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4330 return Flags(smi->value());
4331}
4332
4333
4334String* JSRegExp::Pattern() {
4335 ASSERT(this->data()->IsFixedArray());
4336 Object* data = this->data();
4337 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4338 return pattern;
4339}
4340
4341
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004342Object* JSRegExp::DataAt(int index) {
4343 ASSERT(TypeTag() != NOT_COMPILED);
4344 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004345}
4346
4347
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004348Object* JSRegExp::DataAtUnchecked(int index) {
4349 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4350 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4351 return READ_FIELD(fa, offset);
4352}
4353
4354
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004355void JSRegExp::SetDataAt(int index, Object* value) {
4356 ASSERT(TypeTag() != NOT_COMPILED);
4357 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4358 FixedArray::cast(data())->set(index, value);
4359}
4360
4361
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004362void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4363 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4364 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4365 if (value->IsSmi()) {
4366 fa->set_unchecked(index, Smi::cast(value));
4367 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004368 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004369 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4370 }
4371}
4372
4373
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004374ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004375 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004376#if DEBUG
4377 FixedArrayBase* fixed_array =
4378 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4379 Map* map = fixed_array->map();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004380 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
4381 (map == GetHeap()->fixed_array_map() ||
4382 map == GetHeap()->fixed_cow_array_map())) ||
4383 (IsFastDoubleElementsKind(kind) &&
4384 (fixed_array->IsFixedDoubleArray() ||
4385 fixed_array == GetHeap()->empty_fixed_array())) ||
4386 (kind == DICTIONARY_ELEMENTS &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004387 fixed_array->IsFixedArray() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004388 fixed_array->IsDictionary()) ||
4389 (kind > DICTIONARY_ELEMENTS));
4390 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4391 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004392#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004393 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004394}
4395
4396
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004397ElementsAccessor* JSObject::GetElementsAccessor() {
4398 return ElementsAccessor::ForKind(GetElementsKind());
4399}
4400
4401
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004402bool JSObject::HasFastObjectElements() {
4403 return IsFastObjectElementsKind(GetElementsKind());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004404}
4405
4406
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004407bool JSObject::HasFastSmiElements() {
4408 return IsFastSmiElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004409}
4410
4411
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004412bool JSObject::HasFastSmiOrObjectElements() {
4413 return IsFastSmiOrObjectElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004414}
4415
4416
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004417bool JSObject::HasFastDoubleElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004418 return IsFastDoubleElementsKind(GetElementsKind());
4419}
4420
4421
4422bool JSObject::HasFastHoleyElements() {
4423 return IsFastHoleyElementsKind(GetElementsKind());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004424}
4425
4426
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004427bool JSObject::HasDictionaryElements() {
4428 return GetElementsKind() == DICTIONARY_ELEMENTS;
4429}
4430
4431
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004432bool JSObject::HasNonStrictArgumentsElements() {
4433 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4434}
4435
4436
ager@chromium.org3811b432009-10-28 14:53:37 +00004437bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004438 HeapObject* array = elements();
4439 ASSERT(array != NULL);
4440 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004441}
4442
4443
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004444#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4445bool JSObject::HasExternal##name##Elements() { \
4446 HeapObject* array = elements(); \
4447 ASSERT(array != NULL); \
4448 if (!array->IsHeapObject()) \
4449 return false; \
4450 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004451}
4452
4453
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004454EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4455EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4456EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4457EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4458 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4459EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4460EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4461 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4462EXTERNAL_ELEMENTS_CHECK(Float,
4463 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004464EXTERNAL_ELEMENTS_CHECK(Double,
4465 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004466EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004467
4468
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004469bool JSObject::HasNamedInterceptor() {
4470 return map()->has_named_interceptor();
4471}
4472
4473
4474bool JSObject::HasIndexedInterceptor() {
4475 return map()->has_indexed_interceptor();
4476}
4477
4478
lrn@chromium.org303ada72010-10-27 09:33:13 +00004479MaybeObject* JSObject::EnsureWritableFastElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004480 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004481 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004482 Isolate* isolate = GetIsolate();
4483 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004484 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004485 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4486 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004487 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4488 return maybe_writable_elems;
4489 }
4490 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004491 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004492 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004493 return writable_elems;
4494}
4495
4496
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004497StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004498 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004499 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004500}
4501
4502
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004503SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004504 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004505 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004506}
4507
4508
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004509bool String::IsHashFieldComputed(uint32_t field) {
4510 return (field & kHashNotComputedMask) == 0;
4511}
4512
4513
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004514bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004515 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004516}
4517
4518
4519uint32_t String::Hash() {
4520 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004521 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004522 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004523 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004524 return ComputeAndSetHash();
4525}
4526
4527
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004528StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004529 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004530 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004531 array_index_(0),
4532 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4533 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004534 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004535 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004536}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004537
4538
4539bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004540 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004541}
4542
4543
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004544void StringHasher::AddCharacter(uint32_t c) {
4545 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4546 AddSurrogatePair(c); // Not inlined.
4547 return;
4548 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004549 // Use the Jenkins one-at-a-time hash function to update the hash
4550 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004551 raw_running_hash_ += c;
4552 raw_running_hash_ += (raw_running_hash_ << 10);
4553 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004554 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004555 if (is_array_index_) {
4556 if (c < '0' || c > '9') {
4557 is_array_index_ = false;
4558 } else {
4559 int d = c - '0';
4560 if (is_first_char_) {
4561 is_first_char_ = false;
4562 if (c == '0' && length_ > 1) {
4563 is_array_index_ = false;
4564 return;
4565 }
4566 }
4567 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4568 is_array_index_ = false;
4569 } else {
4570 array_index_ = array_index_ * 10 + d;
4571 }
4572 }
4573 }
4574}
4575
4576
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004577void StringHasher::AddCharacterNoIndex(uint32_t c) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00004578 ASSERT(!is_array_index());
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004579 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4580 AddSurrogatePairNoIndex(c); // Not inlined.
4581 return;
4582 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004583 raw_running_hash_ += c;
4584 raw_running_hash_ += (raw_running_hash_ << 10);
4585 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4586}
4587
4588
4589uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004590 // Get the calculated raw hash value and do some more bit ops to distribute
4591 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004592 uint32_t result = raw_running_hash_;
4593 result += (result << 3);
4594 result ^= (result >> 11);
4595 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004596 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004597 result = 27;
4598 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004599 return result;
4600}
4601
4602
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004603template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004604uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4605 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004606 if (!hasher.has_trivial_hash()) {
4607 int i;
4608 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4609 hasher.AddCharacter(chars[i]);
4610 }
4611 for (; i < length; i++) {
4612 hasher.AddCharacterNoIndex(chars[i]);
4613 }
4614 }
4615 return hasher.GetHashField();
4616}
4617
4618
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004619bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004620 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004621 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4622 return false;
4623 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004624 return SlowAsArrayIndex(index);
4625}
4626
4627
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004628Object* JSReceiver::GetPrototype() {
4629 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004630}
4631
4632
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004633bool JSReceiver::HasProperty(String* name) {
4634 if (IsJSProxy()) {
4635 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4636 }
4637 return GetPropertyAttribute(name) != ABSENT;
4638}
4639
4640
4641bool JSReceiver::HasLocalProperty(String* name) {
4642 if (IsJSProxy()) {
4643 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4644 }
4645 return GetLocalPropertyAttribute(name) != ABSENT;
4646}
4647
4648
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004649PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004650 return GetPropertyAttributeWithReceiver(this, key);
4651}
4652
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004653// TODO(504): this may be useful in other places too where JSGlobalProxy
4654// is used.
4655Object* JSObject::BypassGlobalProxy() {
4656 if (IsJSGlobalProxy()) {
4657 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004658 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004659 ASSERT(proto->IsJSGlobalObject());
4660 return proto;
4661 }
4662 return this;
4663}
4664
4665
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004666MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4667 return IsJSProxy()
4668 ? JSProxy::cast(this)->GetIdentityHash(flag)
4669 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004670}
4671
4672
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004673bool JSReceiver::HasElement(uint32_t index) {
4674 if (IsJSProxy()) {
4675 return JSProxy::cast(this)->HasElementWithHandler(index);
4676 }
4677 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004678}
4679
4680
4681bool AccessorInfo::all_can_read() {
4682 return BooleanBit::get(flag(), kAllCanReadBit);
4683}
4684
4685
4686void AccessorInfo::set_all_can_read(bool value) {
4687 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4688}
4689
4690
4691bool AccessorInfo::all_can_write() {
4692 return BooleanBit::get(flag(), kAllCanWriteBit);
4693}
4694
4695
4696void AccessorInfo::set_all_can_write(bool value) {
4697 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4698}
4699
4700
ager@chromium.org870a0b62008-11-04 11:43:05 +00004701bool AccessorInfo::prohibits_overwriting() {
4702 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4703}
4704
4705
4706void AccessorInfo::set_prohibits_overwriting(bool value) {
4707 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4708}
4709
4710
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004711PropertyAttributes AccessorInfo::property_attributes() {
4712 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4713}
4714
4715
4716void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004717 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004718}
4719
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004720
4721template<typename Shape, typename Key>
4722void Dictionary<Shape, Key>::SetEntry(int entry,
4723 Object* key,
4724 Object* value) {
4725 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4726}
4727
4728
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004729template<typename Shape, typename Key>
4730void Dictionary<Shape, Key>::SetEntry(int entry,
4731 Object* key,
4732 Object* value,
4733 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004734 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004735 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004736 AssertNoAllocation no_gc;
4737 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004738 FixedArray::set(index, key, mode);
4739 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004740 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004741}
4742
4743
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004744bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4745 ASSERT(other->IsNumber());
4746 return key == static_cast<uint32_t>(other->Number());
4747}
4748
4749
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004750uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
4751 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004752}
4753
4754
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004755uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
4756 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004757 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004758 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004759}
4760
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004761uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
4762 return ComputeIntegerHash(key, seed);
4763}
4764
4765uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
4766 uint32_t seed,
4767 Object* other) {
4768 ASSERT(other->IsNumber());
4769 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
4770}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004771
4772MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4773 return Isolate::Current()->heap()->NumberFromUint32(key);
4774}
4775
4776
4777bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4778 // We know that all entries in a hash table had their hash keys created.
4779 // Use that knowledge to have fast failure.
4780 if (key->Hash() != String::cast(other)->Hash()) return false;
4781 return key->Equals(String::cast(other));
4782}
4783
4784
4785uint32_t StringDictionaryShape::Hash(String* key) {
4786 return key->Hash();
4787}
4788
4789
4790uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4791 return String::cast(other)->Hash();
4792}
4793
4794
4795MaybeObject* StringDictionaryShape::AsObject(String* key) {
4796 return key;
4797}
4798
4799
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004800template <int entrysize>
4801bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4802 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004803}
4804
4805
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004806template <int entrysize>
4807uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004808 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4809 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004810}
4811
4812
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004813template <int entrysize>
4814uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4815 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004816 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4817 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004818}
4819
4820
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004821template <int entrysize>
4822MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004823 return key;
4824}
4825
4826
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004827void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004828 // No write barrier is needed since empty_fixed_array is not in new space.
4829 // Please note this function is used during marking:
4830 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00004831 // - IncrementalMarking::Step
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004832 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4833 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004834}
4835
4836
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004837void JSArray::EnsureSize(int required_size) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004838 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004839 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004840 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4841 if (elts->length() < required_size) {
4842 // Doubling in size would be overkill, but leave some slack to avoid
4843 // constantly growing.
4844 Expand(required_size + (required_size >> 3));
4845 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004846 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004847 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4848 // Expand will allocate a new backing store in new space even if the size
4849 // we asked for isn't larger than what we had before.
4850 Expand(required_size);
4851 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004852}
4853
4854
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004855void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004856 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004857 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4858}
4859
4860
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004861bool JSArray::AllowsSetElementsLength() {
4862 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4863 ASSERT(result == !HasExternalArrayElements());
4864 return result;
4865}
4866
4867
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004868MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4869 MaybeObject* maybe_result = EnsureCanContainElements(
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004870 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004871 if (maybe_result->IsFailure()) return maybe_result;
4872 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004873 IsFastDoubleElementsKind(GetElementsKind())) ||
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004874 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004875 (IsFastObjectElementsKind(GetElementsKind()) ||
4876 (IsFastSmiElementsKind(GetElementsKind()) &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004877 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004878 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004879 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004880 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004881}
4882
4883
lrn@chromium.org303ada72010-10-27 09:33:13 +00004884MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004885 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004886 return GetHeap()->CopyFixedArray(this);
4887}
4888
4889
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004890MaybeObject* FixedDoubleArray::Copy() {
4891 if (length() == 0) return this;
4892 return GetHeap()->CopyFixedDoubleArray(this);
4893}
4894
4895
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004896void TypeFeedbackCells::SetAstId(int index, Smi* id) {
4897 set(1 + index * 2, id);
4898}
4899
4900
4901Smi* TypeFeedbackCells::AstId(int index) {
4902 return Smi::cast(get(1 + index * 2));
4903}
4904
4905
4906void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
4907 set(index * 2, cell);
4908}
4909
4910
4911JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
4912 return JSGlobalPropertyCell::cast(get(index * 2));
4913}
4914
4915
4916Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
4917 return isolate->factory()->the_hole_value();
4918}
4919
4920
4921Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
4922 return isolate->factory()->undefined_value();
4923}
4924
4925
4926Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
4927 return heap->raw_unchecked_the_hole_value();
4928}
4929
4930
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004931SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00004932SMI_ACCESSORS(TypeFeedbackInfo, ic_with_type_info_count,
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004933 kIcWithTypeinfoCountOffset)
4934ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
4935 kTypeFeedbackCellsOffset)
4936
4937
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00004938SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
4939
4940
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004941Relocatable::Relocatable(Isolate* isolate) {
4942 ASSERT(isolate == Isolate::Current());
4943 isolate_ = isolate;
4944 prev_ = isolate->relocatable_top();
4945 isolate->set_relocatable_top(this);
4946}
4947
4948
4949Relocatable::~Relocatable() {
4950 ASSERT(isolate_ == Isolate::Current());
4951 ASSERT_EQ(isolate_->relocatable_top(), this);
4952 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004953}
4954
4955
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004956int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4957 return map->instance_size();
4958}
4959
4960
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004961void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004962 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004963 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004964}
4965
4966
4967template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004968void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004969 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004970 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004971}
4972
4973
4974void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4975 typedef v8::String::ExternalAsciiStringResource Resource;
4976 v->VisitExternalAsciiString(
4977 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4978}
4979
4980
4981template<typename StaticVisitor>
4982void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4983 typedef v8::String::ExternalAsciiStringResource Resource;
4984 StaticVisitor::VisitExternalAsciiString(
4985 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4986}
4987
4988
4989void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4990 typedef v8::String::ExternalStringResource Resource;
4991 v->VisitExternalTwoByteString(
4992 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4993}
4994
4995
4996template<typename StaticVisitor>
4997void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4998 typedef v8::String::ExternalStringResource Resource;
4999 StaticVisitor::VisitExternalTwoByteString(
5000 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5001}
5002
5003#define SLOT_ADDR(obj, offset) \
5004 reinterpret_cast<Object**>((obj)->address() + offset)
5005
5006template<int start_offset, int end_offset, int size>
5007void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
5008 HeapObject* obj,
5009 ObjectVisitor* v) {
5010 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
5011}
5012
5013
5014template<int start_offset>
5015void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
5016 int object_size,
5017 ObjectVisitor* v) {
5018 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
5019}
5020
5021#undef SLOT_ADDR
5022
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005023#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005024#undef CAST_ACCESSOR
5025#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005026#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005027#undef ACCESSORS_TO_SMI
5028#undef SMI_ACCESSORS
5029#undef BOOL_GETTER
5030#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005031#undef FIELD_ADDR
5032#undef READ_FIELD
5033#undef WRITE_FIELD
5034#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005035#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005036#undef READ_DOUBLE_FIELD
5037#undef WRITE_DOUBLE_FIELD
5038#undef READ_INT_FIELD
5039#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005040#undef READ_INTPTR_FIELD
5041#undef WRITE_INTPTR_FIELD
5042#undef READ_UINT32_FIELD
5043#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005044#undef READ_SHORT_FIELD
5045#undef WRITE_SHORT_FIELD
5046#undef READ_BYTE_FIELD
5047#undef WRITE_BYTE_FIELD
5048
5049
5050} } // namespace v8::internal
5051
5052#endif // V8_OBJECTS_INL_H_