blob: 0620e0e876ed6cb7754d35f342bfc8ed5117efc9 [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
rossberg@chromium.org400388e2012-06-06 09:29:22 +00001928Object** DescriptorArray::GetKeySlot(int descriptor_number) {
1929 ASSERT(descriptor_number < number_of_descriptors());
1930 return HeapObject::RawField(
1931 reinterpret_cast<HeapObject*>(this),
1932 OffsetOfElementAt(ToKeyIndex(descriptor_number)));
1933}
1934
1935
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001936String* DescriptorArray::GetKey(int descriptor_number) {
1937 ASSERT(descriptor_number < number_of_descriptors());
1938 return String::cast(get(ToKeyIndex(descriptor_number)));
1939}
1940
1941
verwaest@chromium.org37141392012-05-31 13:27:02 +00001942Object** DescriptorArray::GetValueSlot(int descriptor_number) {
1943 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00001944 return HeapObject::RawField(
1945 reinterpret_cast<HeapObject*>(this),
1946 OffsetOfElementAt(ToValueIndex(descriptor_number)));
verwaest@chromium.org37141392012-05-31 13:27:02 +00001947}
1948
1949
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001950Object* DescriptorArray::GetValue(int descriptor_number) {
1951 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00001952 return get(ToValueIndex(descriptor_number));
1953}
1954
1955
1956void DescriptorArray::SetNullValueUnchecked(int descriptor_number, Heap* heap) {
1957 ASSERT(descriptor_number < number_of_descriptors());
1958 set_null_unchecked(heap, ToValueIndex(descriptor_number));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001959}
1960
1961
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001962PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001963 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00001964 Object* details = get(ToDetailsIndex(descriptor_number));
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001965 return PropertyDetails(Smi::cast(details));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001966}
1967
1968
rossberg@chromium.org400388e2012-06-06 09:29:22 +00001969void DescriptorArray::SetDetailsUnchecked(int descriptor_number, Smi* value) {
1970 ASSERT(descriptor_number < number_of_descriptors());
1971 set_unchecked(ToDetailsIndex(descriptor_number), value);
1972}
1973
1974
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001975PropertyType DescriptorArray::GetType(int descriptor_number) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001976 return GetDetails(descriptor_number).type();
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001977}
1978
1979
1980int DescriptorArray::GetFieldIndex(int descriptor_number) {
1981 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1982}
1983
1984
1985JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1986 return JSFunction::cast(GetValue(descriptor_number));
1987}
1988
1989
1990Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1991 ASSERT(GetType(descriptor_number) == CALLBACKS);
1992 return GetValue(descriptor_number);
1993}
1994
1995
1996AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1997 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001998 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001999 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002000}
2001
2002
2003bool DescriptorArray::IsProperty(int descriptor_number) {
ulan@chromium.org9a21ec42012-03-06 08:42:24 +00002004 Entry entry(this, descriptor_number);
2005 return IsPropertyDescriptor(&entry);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002006}
2007
2008
rossberg@chromium.org994edf62012-02-06 10:12:55 +00002009bool DescriptorArray::IsTransitionOnly(int descriptor_number) {
2010 switch (GetType(descriptor_number)) {
2011 case MAP_TRANSITION:
2012 case CONSTANT_TRANSITION:
2013 case ELEMENTS_TRANSITION:
2014 return true;
2015 case CALLBACKS: {
2016 Object* value = GetValue(descriptor_number);
2017 if (!value->IsAccessorPair()) return false;
2018 AccessorPair* accessors = AccessorPair::cast(value);
2019 return accessors->getter()->IsMap() && accessors->setter()->IsMap();
2020 }
2021 case NORMAL:
2022 case FIELD:
2023 case CONSTANT_FUNCTION:
2024 case HANDLER:
2025 case INTERCEPTOR:
2026 case NULL_DESCRIPTOR:
2027 return false;
2028 }
2029 UNREACHABLE(); // Keep the compiler happy.
2030 return false;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002031}
2032
2033
2034bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
2035 return GetType(descriptor_number) == NULL_DESCRIPTOR;
2036}
2037
2038
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002039void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2040 desc->Init(GetKey(descriptor_number),
2041 GetValue(descriptor_number),
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002042 GetDetails(descriptor_number));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002043}
2044
2045
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002046void DescriptorArray::Set(int descriptor_number,
2047 Descriptor* desc,
2048 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002049 // Range check.
2050 ASSERT(descriptor_number < number_of_descriptors());
2051
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002052 NoIncrementalWriteBarrierSet(this,
2053 ToKeyIndex(descriptor_number),
2054 desc->GetKey());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002055 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002056 ToValueIndex(descriptor_number),
2057 desc->GetValue());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002058 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002059 ToDetailsIndex(descriptor_number),
2060 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002061}
2062
2063
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002064void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2065 int first, int second) {
2066 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002067 NoIncrementalWriteBarrierSwap(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002068 ToValueIndex(first),
2069 ToValueIndex(second));
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002070 NoIncrementalWriteBarrierSwap(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002071 ToDetailsIndex(first),
2072 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002073}
2074
2075
2076DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
2077 : marking_(array->GetHeap()->incremental_marking()) {
2078 marking_->EnterNoMarkingScope();
2079 if (array->number_of_descriptors() > 0) {
2080 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002081 }
2082}
2083
2084
2085DescriptorArray::WhitenessWitness::~WhitenessWitness() {
2086 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002087}
2088
2089
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002090template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002091int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2092 const int kMinCapacity = 32;
2093 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2094 if (capacity < kMinCapacity) {
2095 capacity = kMinCapacity; // Guarantee min capacity.
2096 }
2097 return capacity;
2098}
2099
2100
2101template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002102int HashTable<Shape, Key>::FindEntry(Key key) {
2103 return FindEntry(GetIsolate(), key);
2104}
2105
2106
2107// Find entry for key otherwise return kNotFound.
2108template<typename Shape, typename Key>
2109int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2110 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002111 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002112 uint32_t count = 1;
2113 // EnsureCapacity will guarantee the hash table is never full.
2114 while (true) {
2115 Object* element = KeyAt(entry);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002116 // Empty entry.
2117 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2118 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002119 Shape::IsMatch(key, element)) return entry;
2120 entry = NextProbe(entry, count++, capacity);
2121 }
2122 return kNotFound;
2123}
2124
2125
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002126bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002127 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002128 if (!max_index_object->IsSmi()) return false;
2129 return 0 !=
2130 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2131}
2132
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002133uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002134 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002135 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002136 if (!max_index_object->IsSmi()) return 0;
2137 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2138 return value >> kRequiresSlowElementsTagSize;
2139}
2140
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002141void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002142 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002143}
2144
2145
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002146// ------------------------------------
2147// Cast operations
2148
2149
2150CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002151CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002152CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002153CAST_ACCESSOR(DeoptimizationInputData)
2154CAST_ACCESSOR(DeoptimizationOutputData)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002155CAST_ACCESSOR(TypeFeedbackCells)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002156CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002157CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002158CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002159CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002160CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002161CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002162CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002163CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002164CAST_ACCESSOR(String)
2165CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002166CAST_ACCESSOR(SeqAsciiString)
2167CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002168CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002169CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002170CAST_ACCESSOR(ExternalString)
2171CAST_ACCESSOR(ExternalAsciiString)
2172CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002173CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002174CAST_ACCESSOR(JSObject)
2175CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002176CAST_ACCESSOR(HeapObject)
2177CAST_ACCESSOR(HeapNumber)
2178CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002179CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002180CAST_ACCESSOR(SharedFunctionInfo)
2181CAST_ACCESSOR(Map)
2182CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002183CAST_ACCESSOR(GlobalObject)
2184CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002185CAST_ACCESSOR(JSGlobalObject)
2186CAST_ACCESSOR(JSBuiltinsObject)
2187CAST_ACCESSOR(Code)
2188CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002189CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002190CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002191CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002192CAST_ACCESSOR(JSSet)
2193CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002194CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002195CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002196CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002197CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002198CAST_ACCESSOR(ExternalArray)
2199CAST_ACCESSOR(ExternalByteArray)
2200CAST_ACCESSOR(ExternalUnsignedByteArray)
2201CAST_ACCESSOR(ExternalShortArray)
2202CAST_ACCESSOR(ExternalUnsignedShortArray)
2203CAST_ACCESSOR(ExternalIntArray)
2204CAST_ACCESSOR(ExternalUnsignedIntArray)
2205CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002206CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002207CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002208CAST_ACCESSOR(Struct)
2209
2210
2211#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2212 STRUCT_LIST(MAKE_STRUCT_CAST)
2213#undef MAKE_STRUCT_CAST
2214
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002215
2216template <typename Shape, typename Key>
2217HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002218 ASSERT(obj->IsHashTable());
2219 return reinterpret_cast<HashTable*>(obj);
2220}
2221
2222
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002223SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002224SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002225
ager@chromium.orgac091b72010-05-05 07:34:42 +00002226SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002227
2228
2229uint32_t String::hash_field() {
2230 return READ_UINT32_FIELD(this, kHashFieldOffset);
2231}
2232
2233
2234void String::set_hash_field(uint32_t value) {
2235 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002236#if V8_HOST_ARCH_64_BIT
2237 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2238#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002239}
2240
2241
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002242bool String::Equals(String* other) {
2243 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002244 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2245 return false;
2246 }
2247 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002248}
2249
2250
lrn@chromium.org303ada72010-10-27 09:33:13 +00002251MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002252 if (!StringShape(this).IsCons()) return this;
2253 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002254 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002255 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002256}
2257
2258
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002259String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002260 MaybeObject* flat = TryFlatten(pretenure);
2261 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002262 if (!flat->ToObject(&successfully_flattened)) return this;
2263 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002264}
2265
2266
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002267uint16_t String::Get(int index) {
2268 ASSERT(index >= 0 && index < length());
2269 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002270 case kSeqStringTag | kAsciiStringTag:
2271 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2272 case kSeqStringTag | kTwoByteStringTag:
2273 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2274 case kConsStringTag | kAsciiStringTag:
2275 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002276 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002277 case kExternalStringTag | kAsciiStringTag:
2278 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2279 case kExternalStringTag | kTwoByteStringTag:
2280 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002281 case kSlicedStringTag | kAsciiStringTag:
2282 case kSlicedStringTag | kTwoByteStringTag:
2283 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002284 default:
2285 break;
2286 }
2287
2288 UNREACHABLE();
2289 return 0;
2290}
2291
2292
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002293void String::Set(int index, uint16_t value) {
2294 ASSERT(index >= 0 && index < length());
2295 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002296
ager@chromium.org5ec48922009-05-05 07:25:34 +00002297 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002298 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2299 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002300}
2301
2302
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002303bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002304 if (!StringShape(this).IsCons()) return true;
2305 return ConsString::cast(this)->second()->length() == 0;
2306}
2307
2308
2309String* String::GetUnderlying() {
2310 // Giving direct access to underlying string only makes sense if the
2311 // wrapping string is already flattened.
2312 ASSERT(this->IsFlat());
2313 ASSERT(StringShape(this).IsIndirect());
2314 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2315 const int kUnderlyingOffset = SlicedString::kParentOffset;
2316 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002317}
2318
2319
ager@chromium.org7c537e22008-10-16 08:43:32 +00002320uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002321 ASSERT(index >= 0 && index < length());
2322 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2323}
2324
2325
ager@chromium.org7c537e22008-10-16 08:43:32 +00002326void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002327 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2328 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2329 static_cast<byte>(value));
2330}
2331
2332
ager@chromium.org7c537e22008-10-16 08:43:32 +00002333Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002334 return FIELD_ADDR(this, kHeaderSize);
2335}
2336
2337
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002338char* SeqAsciiString::GetChars() {
2339 return reinterpret_cast<char*>(GetCharsAddress());
2340}
2341
2342
ager@chromium.org7c537e22008-10-16 08:43:32 +00002343Address SeqTwoByteString::GetCharsAddress() {
2344 return FIELD_ADDR(this, kHeaderSize);
2345}
2346
2347
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002348uc16* SeqTwoByteString::GetChars() {
2349 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2350}
2351
2352
ager@chromium.org7c537e22008-10-16 08:43:32 +00002353uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002354 ASSERT(index >= 0 && index < length());
2355 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2356}
2357
2358
ager@chromium.org7c537e22008-10-16 08:43:32 +00002359void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002360 ASSERT(index >= 0 && index < length());
2361 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2362}
2363
2364
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002365int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002366 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002367}
2368
2369
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002370int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002371 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002372}
2373
2374
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002375String* SlicedString::parent() {
2376 return String::cast(READ_FIELD(this, kParentOffset));
2377}
2378
2379
2380void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002381 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002382 WRITE_FIELD(this, kParentOffset, parent);
2383}
2384
2385
2386SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2387
2388
ager@chromium.org870a0b62008-11-04 11:43:05 +00002389String* ConsString::first() {
2390 return String::cast(READ_FIELD(this, kFirstOffset));
2391}
2392
2393
2394Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002395 return READ_FIELD(this, kFirstOffset);
2396}
2397
2398
ager@chromium.org870a0b62008-11-04 11:43:05 +00002399void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002400 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002401 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002402}
2403
2404
ager@chromium.org870a0b62008-11-04 11:43:05 +00002405String* ConsString::second() {
2406 return String::cast(READ_FIELD(this, kSecondOffset));
2407}
2408
2409
2410Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002411 return READ_FIELD(this, kSecondOffset);
2412}
2413
2414
ager@chromium.org870a0b62008-11-04 11:43:05 +00002415void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002416 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002417 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002418}
2419
2420
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002421bool ExternalString::is_short() {
2422 InstanceType type = map()->instance_type();
2423 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002424}
2425
2426
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002427const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002428 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2429}
2430
2431
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002432void ExternalAsciiString::update_data_cache() {
2433 if (is_short()) return;
2434 const char** data_field =
2435 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2436 *data_field = resource()->data();
2437}
2438
2439
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002440void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002441 const ExternalAsciiString::Resource* resource) {
2442 *reinterpret_cast<const Resource**>(
2443 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002444 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002445}
2446
2447
2448const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002449 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002450}
2451
2452
2453uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2454 ASSERT(index >= 0 && index < length());
2455 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002456}
2457
2458
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002459const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002460 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2461}
2462
2463
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002464void ExternalTwoByteString::update_data_cache() {
2465 if (is_short()) return;
2466 const uint16_t** data_field =
2467 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2468 *data_field = resource()->data();
2469}
2470
2471
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002472void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002473 const ExternalTwoByteString::Resource* resource) {
2474 *reinterpret_cast<const Resource**>(
2475 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002476 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002477}
2478
2479
2480const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002481 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002482}
2483
2484
2485uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2486 ASSERT(index >= 0 && index < length());
2487 return GetChars()[index];
2488}
2489
2490
2491const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2492 unsigned start) {
2493 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002494}
2495
2496
ager@chromium.orgac091b72010-05-05 07:34:42 +00002497void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002498 set_finger_index(kEntriesIndex);
2499 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002500}
2501
2502
2503void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002504 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002505 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002506 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002507 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002508 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002509 MakeZeroSize();
2510}
2511
2512
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002513int JSFunctionResultCache::size() {
2514 return Smi::cast(get(kCacheSizeIndex))->value();
2515}
2516
2517
2518void JSFunctionResultCache::set_size(int size) {
2519 set(kCacheSizeIndex, Smi::FromInt(size));
2520}
2521
2522
2523int JSFunctionResultCache::finger_index() {
2524 return Smi::cast(get(kFingerIndex))->value();
2525}
2526
2527
2528void JSFunctionResultCache::set_finger_index(int finger_index) {
2529 set(kFingerIndex, Smi::FromInt(finger_index));
2530}
2531
2532
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002533byte ByteArray::get(int index) {
2534 ASSERT(index >= 0 && index < this->length());
2535 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2536}
2537
2538
2539void ByteArray::set(int index, byte value) {
2540 ASSERT(index >= 0 && index < this->length());
2541 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2542}
2543
2544
2545int ByteArray::get_int(int index) {
2546 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2547 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2548}
2549
2550
2551ByteArray* ByteArray::FromDataStartAddress(Address address) {
2552 ASSERT_TAG_ALIGNED(address);
2553 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2554}
2555
2556
2557Address ByteArray::GetDataStartAddress() {
2558 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2559}
2560
2561
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002562uint8_t* ExternalPixelArray::external_pixel_pointer() {
2563 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002564}
2565
2566
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002567uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002568 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002569 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002570 return ptr[index];
2571}
2572
2573
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002574MaybeObject* ExternalPixelArray::get(int index) {
2575 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2576}
2577
2578
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002579void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002580 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002581 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002582 ptr[index] = value;
2583}
2584
2585
ager@chromium.org3811b432009-10-28 14:53:37 +00002586void* ExternalArray::external_pointer() {
2587 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2588 return reinterpret_cast<void*>(ptr);
2589}
2590
2591
2592void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2593 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2594 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2595}
2596
2597
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002598int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002599 ASSERT((index >= 0) && (index < this->length()));
2600 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2601 return ptr[index];
2602}
2603
2604
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002605MaybeObject* ExternalByteArray::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 ExternalByteArray::set(int index, int8_t value) {
2611 ASSERT((index >= 0) && (index < this->length()));
2612 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2613 ptr[index] = value;
2614}
2615
2616
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002617uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002618 ASSERT((index >= 0) && (index < this->length()));
2619 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2620 return ptr[index];
2621}
2622
2623
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002624MaybeObject* ExternalUnsignedByteArray::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 ExternalUnsignedByteArray::set(int index, uint8_t value) {
2630 ASSERT((index >= 0) && (index < this->length()));
2631 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2632 ptr[index] = value;
2633}
2634
2635
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002636int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002637 ASSERT((index >= 0) && (index < this->length()));
2638 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2639 return ptr[index];
2640}
2641
2642
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002643MaybeObject* ExternalShortArray::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 ExternalShortArray::set(int index, int16_t value) {
2649 ASSERT((index >= 0) && (index < this->length()));
2650 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2651 ptr[index] = value;
2652}
2653
2654
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002655uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002656 ASSERT((index >= 0) && (index < this->length()));
2657 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2658 return ptr[index];
2659}
2660
2661
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002662MaybeObject* ExternalUnsignedShortArray::get(int index) {
2663 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2664}
2665
2666
ager@chromium.org3811b432009-10-28 14:53:37 +00002667void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2668 ASSERT((index >= 0) && (index < this->length()));
2669 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2670 ptr[index] = value;
2671}
2672
2673
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002674int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002675 ASSERT((index >= 0) && (index < this->length()));
2676 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2677 return ptr[index];
2678}
2679
2680
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002681MaybeObject* ExternalIntArray::get(int index) {
2682 return GetHeap()->NumberFromInt32(get_scalar(index));
2683}
2684
2685
ager@chromium.org3811b432009-10-28 14:53:37 +00002686void ExternalIntArray::set(int index, int32_t value) {
2687 ASSERT((index >= 0) && (index < this->length()));
2688 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2689 ptr[index] = value;
2690}
2691
2692
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002693uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002694 ASSERT((index >= 0) && (index < this->length()));
2695 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2696 return ptr[index];
2697}
2698
2699
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002700MaybeObject* ExternalUnsignedIntArray::get(int index) {
2701 return GetHeap()->NumberFromUint32(get_scalar(index));
2702}
2703
2704
ager@chromium.org3811b432009-10-28 14:53:37 +00002705void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2706 ASSERT((index >= 0) && (index < this->length()));
2707 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2708 ptr[index] = value;
2709}
2710
2711
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002712float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002713 ASSERT((index >= 0) && (index < this->length()));
2714 float* ptr = static_cast<float*>(external_pointer());
2715 return ptr[index];
2716}
2717
2718
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002719MaybeObject* ExternalFloatArray::get(int index) {
2720 return GetHeap()->NumberFromDouble(get_scalar(index));
2721}
2722
2723
ager@chromium.org3811b432009-10-28 14:53:37 +00002724void ExternalFloatArray::set(int index, float value) {
2725 ASSERT((index >= 0) && (index < this->length()));
2726 float* ptr = static_cast<float*>(external_pointer());
2727 ptr[index] = value;
2728}
2729
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002730
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002731double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002732 ASSERT((index >= 0) && (index < this->length()));
2733 double* ptr = static_cast<double*>(external_pointer());
2734 return ptr[index];
2735}
2736
2737
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002738MaybeObject* ExternalDoubleArray::get(int index) {
2739 return GetHeap()->NumberFromDouble(get_scalar(index));
2740}
2741
2742
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002743void ExternalDoubleArray::set(int index, double value) {
2744 ASSERT((index >= 0) && (index < this->length()));
2745 double* ptr = static_cast<double*>(external_pointer());
2746 ptr[index] = value;
2747}
2748
2749
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002750int Map::visitor_id() {
2751 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2752}
2753
2754
2755void Map::set_visitor_id(int id) {
2756 ASSERT(0 <= id && id < 256);
2757 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2758}
2759
ager@chromium.org3811b432009-10-28 14:53:37 +00002760
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002761int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002762 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2763}
2764
2765
2766int Map::inobject_properties() {
2767 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002768}
2769
2770
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002771int Map::pre_allocated_property_fields() {
2772 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2773}
2774
2775
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002776int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002777 int instance_size = map->instance_size();
2778 if (instance_size != kVariableSizeSentinel) return instance_size;
2779 // We can ignore the "symbol" bit becase it is only set for symbols
2780 // and implies a string type.
2781 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002782 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002783 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002784 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002785 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002786 if (instance_type == ASCII_STRING_TYPE) {
2787 return SeqAsciiString::SizeFor(
2788 reinterpret_cast<SeqAsciiString*>(this)->length());
2789 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002790 if (instance_type == BYTE_ARRAY_TYPE) {
2791 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2792 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002793 if (instance_type == FREE_SPACE_TYPE) {
2794 return reinterpret_cast<FreeSpace*>(this)->size();
2795 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002796 if (instance_type == STRING_TYPE) {
2797 return SeqTwoByteString::SizeFor(
2798 reinterpret_cast<SeqTwoByteString*>(this)->length());
2799 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002800 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2801 return FixedDoubleArray::SizeFor(
2802 reinterpret_cast<FixedDoubleArray*>(this)->length());
2803 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002804 ASSERT(instance_type == CODE_TYPE);
2805 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002806}
2807
2808
2809void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002810 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002811 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002812 ASSERT(0 <= value && value < 256);
2813 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2814}
2815
2816
ager@chromium.org7c537e22008-10-16 08:43:32 +00002817void Map::set_inobject_properties(int value) {
2818 ASSERT(0 <= value && value < 256);
2819 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2820}
2821
2822
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002823void Map::set_pre_allocated_property_fields(int value) {
2824 ASSERT(0 <= value && value < 256);
2825 WRITE_BYTE_FIELD(this,
2826 kPreAllocatedPropertyFieldsOffset,
2827 static_cast<byte>(value));
2828}
2829
2830
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002831InstanceType Map::instance_type() {
2832 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2833}
2834
2835
2836void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002837 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2838}
2839
2840
2841int Map::unused_property_fields() {
2842 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2843}
2844
2845
2846void Map::set_unused_property_fields(int value) {
2847 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2848}
2849
2850
2851byte Map::bit_field() {
2852 return READ_BYTE_FIELD(this, kBitFieldOffset);
2853}
2854
2855
2856void Map::set_bit_field(byte value) {
2857 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2858}
2859
2860
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002861byte Map::bit_field2() {
2862 return READ_BYTE_FIELD(this, kBitField2Offset);
2863}
2864
2865
2866void Map::set_bit_field2(byte value) {
2867 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2868}
2869
2870
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002871void Map::set_non_instance_prototype(bool value) {
2872 if (value) {
2873 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2874 } else {
2875 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2876 }
2877}
2878
2879
2880bool Map::has_non_instance_prototype() {
2881 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2882}
2883
2884
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002885void Map::set_function_with_prototype(bool value) {
2886 if (value) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002887 set_bit_field3(bit_field3() | (1 << kFunctionWithPrototype));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002888 } else {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002889 set_bit_field3(bit_field3() & ~(1 << kFunctionWithPrototype));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002890 }
2891}
2892
2893
2894bool Map::function_with_prototype() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002895 return ((1 << kFunctionWithPrototype) & bit_field3()) != 0;
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002896}
2897
2898
ager@chromium.org870a0b62008-11-04 11:43:05 +00002899void Map::set_is_access_check_needed(bool access_check_needed) {
2900 if (access_check_needed) {
2901 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2902 } else {
2903 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2904 }
2905}
2906
2907
2908bool Map::is_access_check_needed() {
2909 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2910}
2911
2912
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002913void Map::set_is_extensible(bool value) {
2914 if (value) {
2915 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2916 } else {
2917 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2918 }
2919}
2920
2921bool Map::is_extensible() {
2922 return ((1 << kIsExtensible) & bit_field2()) != 0;
2923}
2924
2925
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002926void Map::set_attached_to_shared_function_info(bool value) {
2927 if (value) {
2928 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2929 } else {
2930 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2931 }
2932}
2933
2934bool Map::attached_to_shared_function_info() {
2935 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2936}
2937
2938
2939void Map::set_is_shared(bool value) {
2940 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002941 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002942 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002943 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002944 }
2945}
2946
2947bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002948 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002949}
2950
2951
2952JSFunction* Map::unchecked_constructor() {
2953 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2954}
2955
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002956
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002957Code::Flags Code::flags() {
2958 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2959}
2960
2961
2962void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002963 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002964 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002965 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2966 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002967 ExtractArgumentsCountFromFlags(flags) >= 0);
2968 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2969}
2970
2971
2972Code::Kind Code::kind() {
2973 return ExtractKindFromFlags(flags());
2974}
2975
2976
kasper.lund7276f142008-07-30 08:49:36 +00002977InlineCacheState Code::ic_state() {
2978 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002979 // Only allow uninitialized or debugger states for non-IC code
2980 // objects. This is used in the debugger to determine whether or not
2981 // a call to code object has been replaced with a debug break call.
2982 ASSERT(is_inline_cache_stub() ||
2983 result == UNINITIALIZED ||
2984 result == DEBUG_BREAK ||
2985 result == DEBUG_PREPARE_STEP_IN);
2986 return result;
2987}
2988
2989
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002990Code::ExtraICState Code::extra_ic_state() {
2991 ASSERT(is_inline_cache_stub());
2992 return ExtractExtraICStateFromFlags(flags());
2993}
2994
2995
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002996PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002997 return ExtractTypeFromFlags(flags());
2998}
2999
3000
3001int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003002 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003003 return ExtractArgumentsCountFromFlags(flags());
3004}
3005
3006
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003007int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003008 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003009 kind() == UNARY_OP_IC ||
3010 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003011 kind() == COMPARE_IC ||
3012 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003013 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00003014}
3015
3016
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003017void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003018 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003019 kind() == UNARY_OP_IC ||
3020 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003021 kind() == COMPARE_IC ||
3022 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00003023 ASSERT(0 <= major && major < 256);
3024 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003025}
3026
3027
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003028bool Code::is_pregenerated() {
3029 return kind() == STUB && IsPregeneratedField::decode(flags());
3030}
3031
3032
3033void Code::set_is_pregenerated(bool value) {
3034 ASSERT(kind() == STUB);
3035 Flags f = flags();
3036 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3037 set_flags(f);
3038}
3039
3040
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003041bool Code::optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003042 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003043 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3044}
3045
3046
3047void Code::set_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003048 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003049 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3050}
3051
3052
3053bool Code::has_deoptimization_support() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003054 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003055 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3056 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003057}
3058
3059
3060void Code::set_has_deoptimization_support(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003061 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003062 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3063 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3064 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3065}
3066
3067
3068bool Code::has_debug_break_slots() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003069 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003070 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3071 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3072}
3073
3074
3075void Code::set_has_debug_break_slots(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003076 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003077 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3078 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3079 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003080}
3081
3082
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003083bool Code::is_compiled_optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003084 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003085 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3086 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3087}
3088
3089
3090void Code::set_compiled_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003091 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003092 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3093 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3094 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3095}
3096
3097
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003098int Code::allow_osr_at_loop_nesting_level() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003099 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003100 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3101}
3102
3103
3104void Code::set_allow_osr_at_loop_nesting_level(int level) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003105 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003106 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3107 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3108}
3109
3110
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003111int Code::profiler_ticks() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003112 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003113 return READ_BYTE_FIELD(this, kProfilerTicksOffset);
3114}
3115
3116
3117void Code::set_profiler_ticks(int ticks) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003118 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003119 ASSERT(ticks < 256);
3120 WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
3121}
3122
3123
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003124unsigned Code::stack_slots() {
3125 ASSERT(kind() == OPTIMIZED_FUNCTION);
3126 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3127}
3128
3129
3130void Code::set_stack_slots(unsigned slots) {
3131 ASSERT(kind() == OPTIMIZED_FUNCTION);
3132 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3133}
3134
3135
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003136unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003137 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003138 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003139}
3140
3141
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003142void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003143 ASSERT(kind() == OPTIMIZED_FUNCTION);
3144 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003145 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003146}
3147
3148
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003149unsigned Code::stack_check_table_offset() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003150 ASSERT_EQ(FUNCTION, kind());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003151 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003152}
3153
3154
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003155void Code::set_stack_check_table_offset(unsigned offset) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003156 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003157 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003158 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003159}
3160
3161
3162CheckType Code::check_type() {
3163 ASSERT(is_call_stub() || is_keyed_call_stub());
3164 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3165 return static_cast<CheckType>(type);
3166}
3167
3168
3169void Code::set_check_type(CheckType value) {
3170 ASSERT(is_call_stub() || is_keyed_call_stub());
3171 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3172}
3173
3174
danno@chromium.org40cb8782011-05-25 07:58:50 +00003175byte Code::unary_op_type() {
3176 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003177 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3178}
3179
3180
danno@chromium.org40cb8782011-05-25 07:58:50 +00003181void Code::set_unary_op_type(byte value) {
3182 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003183 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3184}
3185
3186
danno@chromium.org40cb8782011-05-25 07:58:50 +00003187byte Code::binary_op_type() {
3188 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003189 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3190}
3191
3192
danno@chromium.org40cb8782011-05-25 07:58:50 +00003193void Code::set_binary_op_type(byte value) {
3194 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003195 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3196}
3197
3198
danno@chromium.org40cb8782011-05-25 07:58:50 +00003199byte Code::binary_op_result_type() {
3200 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003201 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3202}
3203
3204
danno@chromium.org40cb8782011-05-25 07:58:50 +00003205void Code::set_binary_op_result_type(byte value) {
3206 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003207 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3208}
3209
3210
3211byte Code::compare_state() {
3212 ASSERT(is_compare_ic_stub());
3213 return READ_BYTE_FIELD(this, kCompareStateOffset);
3214}
3215
3216
3217void Code::set_compare_state(byte value) {
3218 ASSERT(is_compare_ic_stub());
3219 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3220}
3221
3222
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003223byte Code::compare_operation() {
3224 ASSERT(is_compare_ic_stub());
3225 return READ_BYTE_FIELD(this, kCompareOperationOffset);
3226}
3227
3228
3229void Code::set_compare_operation(byte value) {
3230 ASSERT(is_compare_ic_stub());
3231 WRITE_BYTE_FIELD(this, kCompareOperationOffset, value);
3232}
3233
3234
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003235byte Code::to_boolean_state() {
3236 ASSERT(is_to_boolean_ic_stub());
3237 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3238}
3239
3240
3241void Code::set_to_boolean_state(byte value) {
3242 ASSERT(is_to_boolean_ic_stub());
3243 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3244}
3245
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003246
3247bool Code::has_function_cache() {
3248 ASSERT(kind() == STUB);
3249 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3250}
3251
3252
3253void Code::set_has_function_cache(bool flag) {
3254 ASSERT(kind() == STUB);
3255 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3256}
3257
3258
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003259bool Code::is_inline_cache_stub() {
3260 Kind kind = this->kind();
3261 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3262}
3263
3264
3265Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003266 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003267 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003268 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003269 int argc,
3270 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003271 // Extra IC state is only allowed for call IC stubs or for store IC
3272 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003273 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003274 kind == CALL_IC ||
3275 kind == STORE_IC ||
3276 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003277 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003278 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003279 | ICStateField::encode(ic_state)
3280 | TypeField::encode(type)
3281 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003282 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003283 | CacheHolderField::encode(holder);
3284 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003285}
3286
3287
3288Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3289 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003290 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003291 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003292 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003293 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003294}
3295
3296
3297Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003298 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003299}
3300
3301
kasper.lund7276f142008-07-30 08:49:36 +00003302InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003303 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003304}
3305
3306
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003307Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003308 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003309}
3310
3311
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003312PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003313 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003314}
3315
3316
3317int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003318 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003319}
3320
3321
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003322InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003323 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003324}
3325
3326
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003327Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003328 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003329 return static_cast<Flags>(bits);
3330}
3331
3332
ager@chromium.org8bb60582008-12-11 12:02:20 +00003333Code* Code::GetCodeFromTargetAddress(Address address) {
3334 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3335 // GetCodeFromTargetAddress might be called when marking objects during mark
3336 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3337 // Code::cast. Code::cast does not work when the object's map is
3338 // marked.
3339 Code* result = reinterpret_cast<Code*>(code);
3340 return result;
3341}
3342
3343
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003344Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3345 return HeapObject::
3346 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3347}
3348
3349
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003350Object* Map::prototype() {
3351 return READ_FIELD(this, kPrototypeOffset);
3352}
3353
3354
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003355void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003356 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003357 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003358 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003359}
3360
3361
danno@chromium.org40cb8782011-05-25 07:58:50 +00003362DescriptorArray* Map::instance_descriptors() {
3363 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3364 if (object->IsSmi()) {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003365 return GetHeap()->empty_descriptor_array();
danno@chromium.org40cb8782011-05-25 07:58:50 +00003366 } else {
3367 return DescriptorArray::cast(object);
3368 }
3369}
3370
3371
3372void Map::init_instance_descriptors() {
3373 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3374}
3375
3376
3377void Map::clear_instance_descriptors() {
3378 Object* object = READ_FIELD(this,
3379 kInstanceDescriptorsOrBitField3Offset);
3380 if (!object->IsSmi()) {
yangguo@chromium.org5f0b8ea2012-05-16 12:37:04 +00003381#ifdef DEBUG
3382 ZapInstanceDescriptors();
3383#endif
danno@chromium.org40cb8782011-05-25 07:58:50 +00003384 WRITE_FIELD(
3385 this,
3386 kInstanceDescriptorsOrBitField3Offset,
3387 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3388 }
3389}
3390
3391
3392void Map::set_instance_descriptors(DescriptorArray* value,
3393 WriteBarrierMode mode) {
3394 Object* object = READ_FIELD(this,
3395 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003396 Heap* heap = GetHeap();
3397 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003398 clear_instance_descriptors();
3399 return;
3400 } else {
3401 if (object->IsSmi()) {
3402 value->set_bit_field3_storage(Smi::cast(object)->value());
3403 } else {
3404 value->set_bit_field3_storage(
3405 DescriptorArray::cast(object)->bit_field3_storage());
3406 }
3407 }
3408 ASSERT(!is_shared());
yangguo@chromium.org5f0b8ea2012-05-16 12:37:04 +00003409#ifdef DEBUG
3410 if (value != instance_descriptors()) {
3411 ZapInstanceDescriptors();
3412 }
3413#endif
danno@chromium.org40cb8782011-05-25 07:58:50 +00003414 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003415 CONDITIONAL_WRITE_BARRIER(
3416 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003417}
3418
3419
3420int Map::bit_field3() {
3421 Object* object = READ_FIELD(this,
3422 kInstanceDescriptorsOrBitField3Offset);
3423 if (object->IsSmi()) {
3424 return Smi::cast(object)->value();
3425 } else {
3426 return DescriptorArray::cast(object)->bit_field3_storage();
3427 }
3428}
3429
3430
3431void Map::set_bit_field3(int value) {
3432 ASSERT(Smi::IsValid(value));
3433 Object* object = READ_FIELD(this,
3434 kInstanceDescriptorsOrBitField3Offset);
3435 if (object->IsSmi()) {
3436 WRITE_FIELD(this,
3437 kInstanceDescriptorsOrBitField3Offset,
3438 Smi::FromInt(value));
3439 } else {
3440 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3441 }
3442}
3443
3444
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003445Object* Map::GetBackPointer() {
3446 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3447 if (object->IsFixedArray()) {
3448 return FixedArray::cast(object)->get(kProtoTransitionBackPointerOffset);
3449 } else {
3450 return object;
3451 }
3452}
3453
3454
3455void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
3456 Heap* heap = GetHeap();
3457 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
3458 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
3459 (value->IsMap() && GetBackPointer()->IsUndefined()));
3460 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3461 if (object->IsFixedArray()) {
3462 FixedArray::cast(object)->set(
3463 kProtoTransitionBackPointerOffset, value, mode);
3464 } else {
3465 WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
3466 CONDITIONAL_WRITE_BARRIER(
3467 heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
3468 }
3469}
3470
3471
3472FixedArray* Map::prototype_transitions() {
3473 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3474 if (object->IsFixedArray()) {
3475 return FixedArray::cast(object);
3476 } else {
3477 return GetHeap()->empty_fixed_array();
3478 }
3479}
3480
3481
3482void Map::set_prototype_transitions(FixedArray* value, WriteBarrierMode mode) {
3483 Heap* heap = GetHeap();
3484 ASSERT(value != heap->empty_fixed_array());
3485 value->set(kProtoTransitionBackPointerOffset, GetBackPointer());
yangguo@chromium.org5f0b8ea2012-05-16 12:37:04 +00003486#ifdef DEBUG
3487 if (value != prototype_transitions()) {
3488 ZapPrototypeTransitions();
3489 }
3490#endif
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003491 WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value);
3492 CONDITIONAL_WRITE_BARRIER(
3493 heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode);
3494}
3495
3496
3497void Map::init_prototype_transitions(Object* undefined) {
3498 ASSERT(undefined->IsUndefined());
3499 WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, undefined);
3500}
3501
3502
3503HeapObject* Map::unchecked_prototype_transitions() {
3504 Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset);
3505 return reinterpret_cast<HeapObject*>(object);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003506}
3507
3508
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003509ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003510ACCESSORS(Map, constructor, Object, kConstructorOffset)
3511
3512ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003513ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003514ACCESSORS(JSFunction,
3515 next_function_link,
3516 Object,
3517 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003518
3519ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3520ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003521ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003522
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003523ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003524
3525ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3526ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3527ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3528ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003529ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003530
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003531ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3532ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3533
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003534ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3535ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3536ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3537
3538ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3539ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3540ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3541ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3542ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3543ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3544
3545ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3546ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3547
3548ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3549ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3550
3551ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3552ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003553ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3554 kPropertyAccessorsOffset)
3555ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3556 kPrototypeTemplateOffset)
3557ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3558ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3559 kNamedPropertyHandlerOffset)
3560ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3561 kIndexedPropertyHandlerOffset)
3562ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3563 kInstanceTemplateOffset)
3564ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3565ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003566ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3567 kInstanceCallHandlerOffset)
3568ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3569 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003570ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003571
3572ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003573ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3574 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003575
3576ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3577ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3578
3579ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3580
3581ACCESSORS(Script, source, Object, kSourceOffset)
3582ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003583ACCESSORS(Script, id, Object, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003584ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
3585ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003586ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003587ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003588ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003589ACCESSORS_TO_SMI(Script, type, kTypeOffset)
3590ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
3591ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003592ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003593ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003594ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
3595 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003596
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003597#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003598ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3599ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3600ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3601ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3602
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00003603ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
3604ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
3605ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003606ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003607#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003608
3609ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003610ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3611ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003612ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3613 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003614ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003615ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3616ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003617ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003618ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3619 kThisPropertyAssignmentsOffset)
danno@chromium.org1044a4d2012-04-30 12:34:39 +00003620SMI_ACCESSORS(SharedFunctionInfo, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003621
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00003622
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003623BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3624 kHiddenPrototypeBit)
3625BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3626BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3627 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003628BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3629 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003630BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3631 kIsExpressionBit)
3632BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3633 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003634BOOL_GETTER(SharedFunctionInfo,
3635 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003636 has_only_simple_this_property_assignments,
3637 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003638BOOL_ACCESSORS(SharedFunctionInfo,
3639 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003640 allows_lazy_compilation,
3641 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003642BOOL_ACCESSORS(SharedFunctionInfo,
3643 compiler_hints,
3644 uses_arguments,
3645 kUsesArguments)
3646BOOL_ACCESSORS(SharedFunctionInfo,
3647 compiler_hints,
3648 has_duplicate_parameters,
3649 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003650
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003651
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003652#if V8_HOST_ARCH_32_BIT
3653SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3654SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003655 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003656SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003657 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003658SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3659SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003660 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003661SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3662SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003663 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003664SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003665 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003666SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003667 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003668SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003669SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3670SMI_ACCESSORS(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003671#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003672
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003673#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003674 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003675 int holder::name() { \
3676 int value = READ_INT_FIELD(this, offset); \
3677 ASSERT(kHeapObjectTag == 1); \
3678 ASSERT((value & kHeapObjectTag) == 0); \
3679 return value >> 1; \
3680 } \
3681 void holder::set_##name(int value) { \
3682 ASSERT(kHeapObjectTag == 1); \
3683 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3684 (value & 0xC0000000) == 0x000000000); \
3685 WRITE_INT_FIELD(this, \
3686 offset, \
3687 (value << 1) & ~kHeapObjectTag); \
3688 }
3689
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003690#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3691 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003692 INT_ACCESSORS(holder, name, offset)
3693
3694
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003695PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003696PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3697 formal_parameter_count,
3698 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003699
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003700PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3701 expected_nof_properties,
3702 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003703PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3704
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003705PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3706PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3707 start_position_and_type,
3708 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003709
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003710PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3711 function_token_position,
3712 kFunctionTokenPositionOffset)
3713PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3714 compiler_hints,
3715 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003716
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003717PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3718 this_property_assignments_count,
3719 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003720PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003721
3722PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3723PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003724#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003725
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003726
3727int SharedFunctionInfo::construction_count() {
3728 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3729}
3730
3731
3732void SharedFunctionInfo::set_construction_count(int value) {
3733 ASSERT(0 <= value && value < 256);
3734 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3735}
3736
3737
whesse@chromium.org7b260152011-06-20 15:33:18 +00003738BOOL_ACCESSORS(SharedFunctionInfo,
3739 compiler_hints,
3740 live_objects_may_exist,
3741 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003742
3743
3744bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003745 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003746}
3747
3748
whesse@chromium.org7b260152011-06-20 15:33:18 +00003749BOOL_GETTER(SharedFunctionInfo,
3750 compiler_hints,
3751 optimization_disabled,
3752 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003753
3754
3755void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3756 set_compiler_hints(BooleanBit::set(compiler_hints(),
3757 kOptimizationDisabled,
3758 disable));
3759 // If disabling optimizations we reflect that in the code object so
3760 // it will not be counted as optimizable code.
3761 if ((code()->kind() == Code::FUNCTION) && disable) {
3762 code()->set_optimizable(false);
3763 }
3764}
3765
3766
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00003767int SharedFunctionInfo::profiler_ticks() {
3768 if (code()->kind() != Code::FUNCTION) return 0;
3769 return code()->profiler_ticks();
3770}
3771
3772
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003773LanguageMode SharedFunctionInfo::language_mode() {
3774 int hints = compiler_hints();
3775 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3776 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3777 return EXTENDED_MODE;
3778 }
3779 return BooleanBit::get(hints, kStrictModeFunction)
3780 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003781}
3782
3783
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003784void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3785 // We only allow language mode transitions that go set the same language mode
3786 // again or go up in the chain:
3787 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3788 ASSERT(this->language_mode() == CLASSIC_MODE ||
3789 this->language_mode() == language_mode ||
3790 language_mode == EXTENDED_MODE);
3791 int hints = compiler_hints();
3792 hints = BooleanBit::set(
3793 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3794 hints = BooleanBit::set(
3795 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3796 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003797}
3798
3799
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003800bool SharedFunctionInfo::is_classic_mode() {
3801 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3802}
3803
3804BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3805 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003806BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3807BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3808 name_should_print_as_anonymous,
3809 kNameShouldPrintAsAnonymous)
3810BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3811BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00003812BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
3813BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
3814 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003815BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003816
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003817ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3818ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3819
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003820ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3821
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003822bool Script::HasValidSource() {
3823 Object* src = this->source();
3824 if (!src->IsString()) return true;
3825 String* src_str = String::cast(src);
3826 if (!StringShape(src_str).IsExternal()) return true;
3827 if (src_str->IsAsciiRepresentation()) {
3828 return ExternalAsciiString::cast(src)->resource() != NULL;
3829 } else if (src_str->IsTwoByteRepresentation()) {
3830 return ExternalTwoByteString::cast(src)->resource() != NULL;
3831 }
3832 return true;
3833}
3834
3835
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003836void SharedFunctionInfo::DontAdaptArguments() {
3837 ASSERT(code()->kind() == Code::BUILTIN);
3838 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3839}
3840
3841
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003842int SharedFunctionInfo::start_position() {
3843 return start_position_and_type() >> kStartPositionShift;
3844}
3845
3846
3847void SharedFunctionInfo::set_start_position(int start_position) {
3848 set_start_position_and_type((start_position << kStartPositionShift)
3849 | (start_position_and_type() & ~kStartPositionMask));
3850}
3851
3852
3853Code* SharedFunctionInfo::code() {
3854 return Code::cast(READ_FIELD(this, kCodeOffset));
3855}
3856
3857
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003858Code* SharedFunctionInfo::unchecked_code() {
3859 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3860}
3861
3862
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003863void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003864 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003865 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003866}
3867
3868
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003869ScopeInfo* SharedFunctionInfo::scope_info() {
3870 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003871}
3872
3873
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003874void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003875 WriteBarrierMode mode) {
3876 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003877 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3878 this,
3879 kScopeInfoOffset,
3880 reinterpret_cast<Object*>(value),
3881 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003882}
3883
3884
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003885bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003886 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003887 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003888}
3889
3890
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003891bool SharedFunctionInfo::IsApiFunction() {
3892 return function_data()->IsFunctionTemplateInfo();
3893}
3894
3895
3896FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3897 ASSERT(IsApiFunction());
3898 return FunctionTemplateInfo::cast(function_data());
3899}
3900
3901
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003902bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003903 return function_data()->IsSmi();
3904}
3905
3906
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003907BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3908 ASSERT(HasBuiltinFunctionId());
3909 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003910}
3911
3912
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003913int SharedFunctionInfo::code_age() {
3914 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3915}
3916
3917
3918void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00003919 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3920 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003921}
3922
3923
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003924bool SharedFunctionInfo::has_deoptimization_support() {
3925 Code* code = this->code();
3926 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3927}
3928
3929
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003930bool JSFunction::IsBuiltin() {
3931 return context()->global()->IsJSBuiltinsObject();
3932}
3933
3934
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003935bool JSFunction::NeedsArgumentsAdaption() {
3936 return shared()->formal_parameter_count() !=
3937 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3938}
3939
3940
3941bool JSFunction::IsOptimized() {
3942 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3943}
3944
3945
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003946bool JSFunction::IsOptimizable() {
3947 return code()->kind() == Code::FUNCTION && code()->optimizable();
3948}
3949
3950
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003951bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003952 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003953}
3954
3955
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003956Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003957 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003958}
3959
3960
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003961Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003962 return reinterpret_cast<Code*>(
3963 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003964}
3965
3966
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003967void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003968 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003969 Address entry = value->entry();
3970 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003971 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3972 this,
3973 HeapObject::RawField(this, kCodeEntryOffset),
3974 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003975}
3976
3977
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003978void JSFunction::ReplaceCode(Code* code) {
3979 bool was_optimized = IsOptimized();
3980 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3981
3982 set_code(code);
3983
3984 // Add/remove the function from the list of optimized functions for this
3985 // context based on the state change.
3986 if (!was_optimized && is_optimized) {
3987 context()->global_context()->AddOptimizedFunction(this);
3988 }
3989 if (was_optimized && !is_optimized) {
3990 context()->global_context()->RemoveOptimizedFunction(this);
3991 }
3992}
3993
3994
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003995Context* JSFunction::context() {
3996 return Context::cast(READ_FIELD(this, kContextOffset));
3997}
3998
3999
4000Object* JSFunction::unchecked_context() {
4001 return READ_FIELD(this, kContextOffset);
4002}
4003
4004
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004005SharedFunctionInfo* JSFunction::unchecked_shared() {
4006 return reinterpret_cast<SharedFunctionInfo*>(
4007 READ_FIELD(this, kSharedFunctionInfoOffset));
4008}
4009
4010
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004011void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004012 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004013 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004014 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004015}
4016
4017ACCESSORS(JSFunction, prototype_or_initial_map, Object,
4018 kPrototypeOrInitialMapOffset)
4019
4020
4021Map* JSFunction::initial_map() {
4022 return Map::cast(prototype_or_initial_map());
4023}
4024
4025
4026void JSFunction::set_initial_map(Map* value) {
4027 set_prototype_or_initial_map(value);
4028}
4029
4030
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004031MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
4032 Map* initial_map) {
4033 Context* global_context = context()->global_context();
4034 Object* array_function =
4035 global_context->get(Context::ARRAY_FUNCTION_INDEX);
4036 if (array_function->IsJSFunction() &&
4037 this == JSFunction::cast(array_function)) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004038 // Replace all of the cached initial array maps in the global context with
4039 // the appropriate transitioned elements kind maps.
4040 Heap* heap = GetHeap();
4041 MaybeObject* maybe_maps =
4042 heap->AllocateFixedArrayWithHoles(kElementsKindCount);
4043 FixedArray* maps;
4044 if (!maybe_maps->To(&maps)) return maybe_maps;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004045
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004046 Map* current_map = initial_map;
4047 ElementsKind kind = current_map->elements_kind();
4048 ASSERT(kind == GetInitialFastElementsKind());
4049 maps->set(kind, current_map);
4050 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
4051 i < kFastElementsKindCount; ++i) {
4052 ElementsKind transitioned_kind = GetFastElementsKindFromSequenceIndex(i);
4053 MaybeObject* maybe_new_map = current_map->CopyDropTransitions();
4054 Map* new_map = NULL;
4055 if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map;
4056 new_map->set_elements_kind(transitioned_kind);
4057 maybe_new_map = current_map->AddElementsTransition(transitioned_kind,
4058 new_map);
4059 if (maybe_new_map->IsFailure()) return maybe_new_map;
4060 maps->set(transitioned_kind, new_map);
4061 current_map = new_map;
4062 }
4063 global_context->set_js_array_maps(maps);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004064 }
4065 set_initial_map(initial_map);
4066 return this;
4067}
4068
4069
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004070bool JSFunction::has_initial_map() {
4071 return prototype_or_initial_map()->IsMap();
4072}
4073
4074
4075bool JSFunction::has_instance_prototype() {
4076 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4077}
4078
4079
4080bool JSFunction::has_prototype() {
4081 return map()->has_non_instance_prototype() || has_instance_prototype();
4082}
4083
4084
4085Object* JSFunction::instance_prototype() {
4086 ASSERT(has_instance_prototype());
4087 if (has_initial_map()) return initial_map()->prototype();
4088 // When there is no initial map and the prototype is a JSObject, the
4089 // initial map field is used for the prototype field.
4090 return prototype_or_initial_map();
4091}
4092
4093
4094Object* JSFunction::prototype() {
4095 ASSERT(has_prototype());
4096 // If the function's prototype property has been set to a non-JSObject
4097 // value, that value is stored in the constructor field of the map.
4098 if (map()->has_non_instance_prototype()) return map()->constructor();
4099 return instance_prototype();
4100}
4101
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00004102bool JSFunction::should_have_prototype() {
4103 return map()->function_with_prototype();
4104}
4105
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004106
4107bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004108 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004109}
4110
4111
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004112FixedArray* JSFunction::literals() {
4113 ASSERT(!shared()->bound());
4114 return literals_or_bindings();
4115}
4116
4117
4118void JSFunction::set_literals(FixedArray* literals) {
4119 ASSERT(!shared()->bound());
4120 set_literals_or_bindings(literals);
4121}
4122
4123
4124FixedArray* JSFunction::function_bindings() {
4125 ASSERT(shared()->bound());
4126 return literals_or_bindings();
4127}
4128
4129
4130void JSFunction::set_function_bindings(FixedArray* bindings) {
4131 ASSERT(shared()->bound());
4132 // Bound function literal may be initialized to the empty fixed array
4133 // before the bindings are set.
4134 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4135 bindings->map() == GetHeap()->fixed_cow_array_map());
4136 set_literals_or_bindings(bindings);
4137}
4138
4139
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004140int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004141 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004142 return literals()->length();
4143}
4144
4145
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004146Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004147 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004148 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004149}
4150
4151
4152void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4153 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004154 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004155 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004156 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004157}
4158
4159
4160Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004161 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004162 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4163}
4164
4165
4166void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4167 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004168 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004169 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004170 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004171}
4172
4173
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004174ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004175ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004176ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4177ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4178
4179
4180void JSProxy::InitializeBody(int object_size, Object* value) {
4181 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4182 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4183 WRITE_FIELD(this, offset, value);
4184 }
4185}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004186
4187
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004188ACCESSORS(JSSet, table, Object, kTableOffset)
4189ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004190ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4191ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004192
4193
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004194Address Foreign::foreign_address() {
4195 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004196}
4197
4198
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004199void Foreign::set_foreign_address(Address value) {
4200 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004201}
4202
4203
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004204ACCESSORS(JSModule, context, Object, kContextOffset)
4205
4206
4207JSModule* JSModule::cast(Object* obj) {
4208 ASSERT(obj->IsJSModule());
4209 ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
4210 return reinterpret_cast<JSModule*>(obj);
4211}
4212
4213
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004214ACCESSORS(JSValue, value, Object, kValueOffset)
4215
4216
4217JSValue* JSValue::cast(Object* obj) {
4218 ASSERT(obj->IsJSValue());
4219 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4220 return reinterpret_cast<JSValue*>(obj);
4221}
4222
4223
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004224ACCESSORS(JSDate, value, Object, kValueOffset)
4225ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4226ACCESSORS(JSDate, year, Object, kYearOffset)
4227ACCESSORS(JSDate, month, Object, kMonthOffset)
4228ACCESSORS(JSDate, day, Object, kDayOffset)
4229ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4230ACCESSORS(JSDate, hour, Object, kHourOffset)
4231ACCESSORS(JSDate, min, Object, kMinOffset)
4232ACCESSORS(JSDate, sec, Object, kSecOffset)
4233
4234
4235JSDate* JSDate::cast(Object* obj) {
4236 ASSERT(obj->IsJSDate());
4237 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4238 return reinterpret_cast<JSDate*>(obj);
4239}
4240
4241
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004242ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4243ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4244ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4245ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4246ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4247SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4248SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4249
4250
4251JSMessageObject* JSMessageObject::cast(Object* obj) {
4252 ASSERT(obj->IsJSMessageObject());
4253 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4254 return reinterpret_cast<JSMessageObject*>(obj);
4255}
4256
4257
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004258INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004259ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004260ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004261ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004262ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004263ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00004264INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004265
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004266byte* Code::instruction_start() {
4267 return FIELD_ADDR(this, kHeaderSize);
4268}
4269
4270
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004271byte* Code::instruction_end() {
4272 return instruction_start() + instruction_size();
4273}
4274
4275
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004276int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004277 return RoundUp(instruction_size(), kObjectAlignment);
4278}
4279
4280
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004281FixedArray* Code::unchecked_deoptimization_data() {
4282 return reinterpret_cast<FixedArray*>(
4283 READ_FIELD(this, kDeoptimizationDataOffset));
4284}
4285
4286
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004287ByteArray* Code::unchecked_relocation_info() {
4288 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004289}
4290
4291
4292byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004293 return unchecked_relocation_info()->GetDataStartAddress();
4294}
4295
4296
4297int Code::relocation_size() {
4298 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004299}
4300
4301
4302byte* Code::entry() {
4303 return instruction_start();
4304}
4305
4306
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004307bool Code::contains(byte* inner_pointer) {
4308 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004309}
4310
4311
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004312ACCESSORS(JSArray, length, Object, kLengthOffset)
4313
4314
ager@chromium.org236ad962008-09-25 09:45:57 +00004315ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004316
4317
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004318JSRegExp::Type JSRegExp::TypeTag() {
4319 Object* data = this->data();
4320 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4321 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4322 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004323}
4324
4325
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004326JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4327 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4328 return static_cast<JSRegExp::Type>(smi->value());
4329}
4330
4331
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004332int JSRegExp::CaptureCount() {
4333 switch (TypeTag()) {
4334 case ATOM:
4335 return 0;
4336 case IRREGEXP:
4337 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4338 default:
4339 UNREACHABLE();
4340 return -1;
4341 }
4342}
4343
4344
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004345JSRegExp::Flags JSRegExp::GetFlags() {
4346 ASSERT(this->data()->IsFixedArray());
4347 Object* data = this->data();
4348 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4349 return Flags(smi->value());
4350}
4351
4352
4353String* JSRegExp::Pattern() {
4354 ASSERT(this->data()->IsFixedArray());
4355 Object* data = this->data();
4356 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4357 return pattern;
4358}
4359
4360
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004361Object* JSRegExp::DataAt(int index) {
4362 ASSERT(TypeTag() != NOT_COMPILED);
4363 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004364}
4365
4366
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004367Object* JSRegExp::DataAtUnchecked(int index) {
4368 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4369 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4370 return READ_FIELD(fa, offset);
4371}
4372
4373
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004374void JSRegExp::SetDataAt(int index, Object* value) {
4375 ASSERT(TypeTag() != NOT_COMPILED);
4376 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4377 FixedArray::cast(data())->set(index, value);
4378}
4379
4380
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004381void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4382 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4383 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4384 if (value->IsSmi()) {
4385 fa->set_unchecked(index, Smi::cast(value));
4386 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004387 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004388 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4389 }
4390}
4391
4392
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004393ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004394 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004395#if DEBUG
4396 FixedArrayBase* fixed_array =
4397 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4398 Map* map = fixed_array->map();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004399 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
4400 (map == GetHeap()->fixed_array_map() ||
4401 map == GetHeap()->fixed_cow_array_map())) ||
4402 (IsFastDoubleElementsKind(kind) &&
4403 (fixed_array->IsFixedDoubleArray() ||
4404 fixed_array == GetHeap()->empty_fixed_array())) ||
4405 (kind == DICTIONARY_ELEMENTS &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004406 fixed_array->IsFixedArray() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004407 fixed_array->IsDictionary()) ||
4408 (kind > DICTIONARY_ELEMENTS));
4409 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4410 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004411#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004412 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004413}
4414
4415
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004416ElementsAccessor* JSObject::GetElementsAccessor() {
4417 return ElementsAccessor::ForKind(GetElementsKind());
4418}
4419
4420
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004421bool JSObject::HasFastObjectElements() {
4422 return IsFastObjectElementsKind(GetElementsKind());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004423}
4424
4425
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004426bool JSObject::HasFastSmiElements() {
4427 return IsFastSmiElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004428}
4429
4430
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004431bool JSObject::HasFastSmiOrObjectElements() {
4432 return IsFastSmiOrObjectElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004433}
4434
4435
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004436bool JSObject::HasFastDoubleElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004437 return IsFastDoubleElementsKind(GetElementsKind());
4438}
4439
4440
4441bool JSObject::HasFastHoleyElements() {
4442 return IsFastHoleyElementsKind(GetElementsKind());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004443}
4444
4445
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004446bool JSObject::HasDictionaryElements() {
4447 return GetElementsKind() == DICTIONARY_ELEMENTS;
4448}
4449
4450
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004451bool JSObject::HasNonStrictArgumentsElements() {
4452 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4453}
4454
4455
ager@chromium.org3811b432009-10-28 14:53:37 +00004456bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004457 HeapObject* array = elements();
4458 ASSERT(array != NULL);
4459 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004460}
4461
4462
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004463#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4464bool JSObject::HasExternal##name##Elements() { \
4465 HeapObject* array = elements(); \
4466 ASSERT(array != NULL); \
4467 if (!array->IsHeapObject()) \
4468 return false; \
4469 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004470}
4471
4472
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004473EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4474EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4475EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4476EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4477 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4478EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4479EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4480 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4481EXTERNAL_ELEMENTS_CHECK(Float,
4482 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004483EXTERNAL_ELEMENTS_CHECK(Double,
4484 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004485EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004486
4487
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004488bool JSObject::HasNamedInterceptor() {
4489 return map()->has_named_interceptor();
4490}
4491
4492
4493bool JSObject::HasIndexedInterceptor() {
4494 return map()->has_indexed_interceptor();
4495}
4496
4497
lrn@chromium.org303ada72010-10-27 09:33:13 +00004498MaybeObject* JSObject::EnsureWritableFastElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004499 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004500 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004501 Isolate* isolate = GetIsolate();
4502 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004503 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004504 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4505 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004506 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4507 return maybe_writable_elems;
4508 }
4509 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004510 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004511 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004512 return writable_elems;
4513}
4514
4515
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004516StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004517 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004518 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004519}
4520
4521
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004522SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004523 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004524 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004525}
4526
4527
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004528bool String::IsHashFieldComputed(uint32_t field) {
4529 return (field & kHashNotComputedMask) == 0;
4530}
4531
4532
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004533bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004534 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004535}
4536
4537
4538uint32_t String::Hash() {
4539 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004540 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004541 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004542 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004543 return ComputeAndSetHash();
4544}
4545
4546
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004547StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004548 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004549 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004550 array_index_(0),
4551 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4552 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004553 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004554 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004555}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004556
4557
4558bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004559 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004560}
4561
4562
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004563void StringHasher::AddCharacter(uint32_t c) {
4564 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4565 AddSurrogatePair(c); // Not inlined.
4566 return;
4567 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004568 // Use the Jenkins one-at-a-time hash function to update the hash
4569 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004570 raw_running_hash_ += c;
4571 raw_running_hash_ += (raw_running_hash_ << 10);
4572 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004573 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004574 if (is_array_index_) {
4575 if (c < '0' || c > '9') {
4576 is_array_index_ = false;
4577 } else {
4578 int d = c - '0';
4579 if (is_first_char_) {
4580 is_first_char_ = false;
4581 if (c == '0' && length_ > 1) {
4582 is_array_index_ = false;
4583 return;
4584 }
4585 }
4586 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4587 is_array_index_ = false;
4588 } else {
4589 array_index_ = array_index_ * 10 + d;
4590 }
4591 }
4592 }
4593}
4594
4595
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004596void StringHasher::AddCharacterNoIndex(uint32_t c) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00004597 ASSERT(!is_array_index());
yangguo@chromium.org154ff992012-03-13 08:09:54 +00004598 if (c > unibrow::Utf16::kMaxNonSurrogateCharCode) {
4599 AddSurrogatePairNoIndex(c); // Not inlined.
4600 return;
4601 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004602 raw_running_hash_ += c;
4603 raw_running_hash_ += (raw_running_hash_ << 10);
4604 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4605}
4606
4607
4608uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004609 // Get the calculated raw hash value and do some more bit ops to distribute
4610 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004611 uint32_t result = raw_running_hash_;
4612 result += (result << 3);
4613 result ^= (result >> 11);
4614 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004615 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004616 result = 27;
4617 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004618 return result;
4619}
4620
4621
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004622template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004623uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4624 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004625 if (!hasher.has_trivial_hash()) {
4626 int i;
4627 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4628 hasher.AddCharacter(chars[i]);
4629 }
4630 for (; i < length; i++) {
4631 hasher.AddCharacterNoIndex(chars[i]);
4632 }
4633 }
4634 return hasher.GetHashField();
4635}
4636
4637
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004638bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004639 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004640 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4641 return false;
4642 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004643 return SlowAsArrayIndex(index);
4644}
4645
4646
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004647Object* JSReceiver::GetPrototype() {
4648 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004649}
4650
4651
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004652bool JSReceiver::HasProperty(String* name) {
4653 if (IsJSProxy()) {
4654 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4655 }
4656 return GetPropertyAttribute(name) != ABSENT;
4657}
4658
4659
4660bool JSReceiver::HasLocalProperty(String* name) {
4661 if (IsJSProxy()) {
4662 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4663 }
4664 return GetLocalPropertyAttribute(name) != ABSENT;
4665}
4666
4667
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004668PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004669 return GetPropertyAttributeWithReceiver(this, key);
4670}
4671
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004672// TODO(504): this may be useful in other places too where JSGlobalProxy
4673// is used.
4674Object* JSObject::BypassGlobalProxy() {
4675 if (IsJSGlobalProxy()) {
4676 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004677 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004678 ASSERT(proto->IsJSGlobalObject());
4679 return proto;
4680 }
4681 return this;
4682}
4683
4684
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004685MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4686 return IsJSProxy()
4687 ? JSProxy::cast(this)->GetIdentityHash(flag)
4688 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004689}
4690
4691
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004692bool JSReceiver::HasElement(uint32_t index) {
4693 if (IsJSProxy()) {
4694 return JSProxy::cast(this)->HasElementWithHandler(index);
4695 }
4696 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004697}
4698
4699
4700bool AccessorInfo::all_can_read() {
4701 return BooleanBit::get(flag(), kAllCanReadBit);
4702}
4703
4704
4705void AccessorInfo::set_all_can_read(bool value) {
4706 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4707}
4708
4709
4710bool AccessorInfo::all_can_write() {
4711 return BooleanBit::get(flag(), kAllCanWriteBit);
4712}
4713
4714
4715void AccessorInfo::set_all_can_write(bool value) {
4716 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4717}
4718
4719
ager@chromium.org870a0b62008-11-04 11:43:05 +00004720bool AccessorInfo::prohibits_overwriting() {
4721 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4722}
4723
4724
4725void AccessorInfo::set_prohibits_overwriting(bool value) {
4726 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4727}
4728
4729
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004730PropertyAttributes AccessorInfo::property_attributes() {
4731 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4732}
4733
4734
4735void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004736 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004737}
4738
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004739
4740template<typename Shape, typename Key>
4741void Dictionary<Shape, Key>::SetEntry(int entry,
4742 Object* key,
4743 Object* value) {
4744 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4745}
4746
4747
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004748template<typename Shape, typename Key>
4749void Dictionary<Shape, Key>::SetEntry(int entry,
4750 Object* key,
4751 Object* value,
4752 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004753 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004754 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004755 AssertNoAllocation no_gc;
4756 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004757 FixedArray::set(index, key, mode);
4758 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004759 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004760}
4761
4762
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004763bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4764 ASSERT(other->IsNumber());
4765 return key == static_cast<uint32_t>(other->Number());
4766}
4767
4768
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004769uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
4770 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004771}
4772
4773
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004774uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
4775 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004776 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004777 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004778}
4779
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004780uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
4781 return ComputeIntegerHash(key, seed);
4782}
4783
4784uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
4785 uint32_t seed,
4786 Object* other) {
4787 ASSERT(other->IsNumber());
4788 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
4789}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004790
4791MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4792 return Isolate::Current()->heap()->NumberFromUint32(key);
4793}
4794
4795
4796bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4797 // We know that all entries in a hash table had their hash keys created.
4798 // Use that knowledge to have fast failure.
4799 if (key->Hash() != String::cast(other)->Hash()) return false;
4800 return key->Equals(String::cast(other));
4801}
4802
4803
4804uint32_t StringDictionaryShape::Hash(String* key) {
4805 return key->Hash();
4806}
4807
4808
4809uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4810 return String::cast(other)->Hash();
4811}
4812
4813
4814MaybeObject* StringDictionaryShape::AsObject(String* key) {
4815 return key;
4816}
4817
4818
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004819template <int entrysize>
4820bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4821 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004822}
4823
4824
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004825template <int entrysize>
4826uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004827 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4828 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004829}
4830
4831
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004832template <int entrysize>
4833uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4834 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004835 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4836 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004837}
4838
4839
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004840template <int entrysize>
4841MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004842 return key;
4843}
4844
4845
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004846void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004847 // No write barrier is needed since empty_fixed_array is not in new space.
4848 // Please note this function is used during marking:
4849 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00004850 // - IncrementalMarking::Step
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004851 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4852 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004853}
4854
4855
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004856void JSArray::EnsureSize(int required_size) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004857 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004858 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004859 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4860 if (elts->length() < required_size) {
4861 // Doubling in size would be overkill, but leave some slack to avoid
4862 // constantly growing.
4863 Expand(required_size + (required_size >> 3));
4864 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004865 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004866 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4867 // Expand will allocate a new backing store in new space even if the size
4868 // we asked for isn't larger than what we had before.
4869 Expand(required_size);
4870 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004871}
4872
4873
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004874void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004875 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004876 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4877}
4878
4879
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004880bool JSArray::AllowsSetElementsLength() {
4881 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4882 ASSERT(result == !HasExternalArrayElements());
4883 return result;
4884}
4885
4886
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004887MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4888 MaybeObject* maybe_result = EnsureCanContainElements(
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004889 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004890 if (maybe_result->IsFailure()) return maybe_result;
4891 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004892 IsFastDoubleElementsKind(GetElementsKind())) ||
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004893 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00004894 (IsFastObjectElementsKind(GetElementsKind()) ||
4895 (IsFastSmiElementsKind(GetElementsKind()) &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004896 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004897 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004898 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004899 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004900}
4901
4902
lrn@chromium.org303ada72010-10-27 09:33:13 +00004903MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004904 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004905 return GetHeap()->CopyFixedArray(this);
4906}
4907
4908
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004909MaybeObject* FixedDoubleArray::Copy() {
4910 if (length() == 0) return this;
4911 return GetHeap()->CopyFixedDoubleArray(this);
4912}
4913
4914
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004915void TypeFeedbackCells::SetAstId(int index, Smi* id) {
4916 set(1 + index * 2, id);
4917}
4918
4919
4920Smi* TypeFeedbackCells::AstId(int index) {
4921 return Smi::cast(get(1 + index * 2));
4922}
4923
4924
4925void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
4926 set(index * 2, cell);
4927}
4928
4929
4930JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
4931 return JSGlobalPropertyCell::cast(get(index * 2));
4932}
4933
4934
4935Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
4936 return isolate->factory()->the_hole_value();
4937}
4938
4939
4940Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
4941 return isolate->factory()->undefined_value();
4942}
4943
4944
4945Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
4946 return heap->raw_unchecked_the_hole_value();
4947}
4948
4949
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004950SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00004951SMI_ACCESSORS(TypeFeedbackInfo, ic_with_type_info_count,
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004952 kIcWithTypeinfoCountOffset)
4953ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
4954 kTypeFeedbackCellsOffset)
4955
4956
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00004957SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
4958
4959
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004960Relocatable::Relocatable(Isolate* isolate) {
4961 ASSERT(isolate == Isolate::Current());
4962 isolate_ = isolate;
4963 prev_ = isolate->relocatable_top();
4964 isolate->set_relocatable_top(this);
4965}
4966
4967
4968Relocatable::~Relocatable() {
4969 ASSERT(isolate_ == Isolate::Current());
4970 ASSERT_EQ(isolate_->relocatable_top(), this);
4971 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004972}
4973
4974
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004975int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4976 return map->instance_size();
4977}
4978
4979
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004980void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004981 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004982 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004983}
4984
4985
4986template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004987void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004988 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004989 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004990}
4991
4992
4993void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4994 typedef v8::String::ExternalAsciiStringResource Resource;
4995 v->VisitExternalAsciiString(
4996 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4997}
4998
4999
5000template<typename StaticVisitor>
5001void ExternalAsciiString::ExternalAsciiStringIterateBody() {
5002 typedef v8::String::ExternalAsciiStringResource Resource;
5003 StaticVisitor::VisitExternalAsciiString(
5004 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5005}
5006
5007
5008void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
5009 typedef v8::String::ExternalStringResource Resource;
5010 v->VisitExternalTwoByteString(
5011 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5012}
5013
5014
5015template<typename StaticVisitor>
5016void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
5017 typedef v8::String::ExternalStringResource Resource;
5018 StaticVisitor::VisitExternalTwoByteString(
5019 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
5020}
5021
5022#define SLOT_ADDR(obj, offset) \
5023 reinterpret_cast<Object**>((obj)->address() + offset)
5024
5025template<int start_offset, int end_offset, int size>
5026void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
5027 HeapObject* obj,
5028 ObjectVisitor* v) {
5029 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
5030}
5031
5032
5033template<int start_offset>
5034void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
5035 int object_size,
5036 ObjectVisitor* v) {
5037 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
5038}
5039
5040#undef SLOT_ADDR
5041
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005042#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005043#undef CAST_ACCESSOR
5044#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005045#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005046#undef ACCESSORS_TO_SMI
5047#undef SMI_ACCESSORS
5048#undef BOOL_GETTER
5049#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005050#undef FIELD_ADDR
5051#undef READ_FIELD
5052#undef WRITE_FIELD
5053#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005054#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005055#undef READ_DOUBLE_FIELD
5056#undef WRITE_DOUBLE_FIELD
5057#undef READ_INT_FIELD
5058#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00005059#undef READ_INTPTR_FIELD
5060#undef WRITE_INTPTR_FIELD
5061#undef READ_UINT32_FIELD
5062#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005063#undef READ_SHORT_FIELD
5064#undef WRITE_SHORT_FIELD
5065#undef READ_BYTE_FIELD
5066#undef WRITE_BYTE_FIELD
5067
5068
5069} } // namespace v8::internal
5070
5071#endif // V8_OBJECTS_INL_H_