blob: ea347fd354bcb77a2c7240a3b3bcd275cf86a53a [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"
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000050#include "transitions-inl.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000051
kasperl@chromium.org71affb52009-05-26 05:44:31 +000052namespace v8 {
53namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000054
55PropertyDetails::PropertyDetails(Smi* smi) {
56 value_ = smi->value();
57}
58
59
60Smi* PropertyDetails::AsSmi() {
rossberg@chromium.org79e79022013-06-03 15:43:46 +000061 // Ensure the upper 2 bits have the same value by sign extending it. This is
62 // necessary to be able to use the 31st bit of the property details.
63 int value = value_ << 1;
64 return Smi::FromInt(value >> 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000065}
66
67
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000068PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000069 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000070 return PropertyDetails(smi);
71}
72
73
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000074#define TYPE_CHECKER(type, instancetype) \
75 bool Object::Is##type() { \
76 return Object::IsHeapObject() && \
77 HeapObject::cast(this)->map()->instance_type() == instancetype; \
78 }
79
80
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000081#define CAST_ACCESSOR(type) \
82 type* type::cast(Object* object) { \
83 ASSERT(object->Is##type()); \
84 return reinterpret_cast<type*>(object); \
85 }
86
87
88#define INT_ACCESSORS(holder, name, offset) \
89 int holder::name() { return READ_INT_FIELD(this, offset); } \
90 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
91
92
93#define ACCESSORS(holder, name, type, offset) \
94 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000095 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000096 WRITE_FIELD(this, offset, value); \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000097 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000098 }
99
100
rossberg@chromium.org2c067b12012-03-19 11:01:52 +0000101// Getter that returns a tagged Smi and setter that writes a tagged Smi.
102#define ACCESSORS_TO_SMI(holder, name, offset) \
103 Smi* holder::name() { return Smi::cast(READ_FIELD(this, offset)); } \
104 void holder::set_##name(Smi* value, WriteBarrierMode mode) { \
105 WRITE_FIELD(this, offset, value); \
106 }
107
108
109// Getter that returns a Smi as an int and writes an int as a Smi.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000110#define SMI_ACCESSORS(holder, name, offset) \
111 int holder::name() { \
112 Object* value = READ_FIELD(this, offset); \
113 return Smi::cast(value)->value(); \
114 } \
115 void holder::set_##name(int value) { \
116 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
117 }
118
119
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000120#define BOOL_GETTER(holder, field, name, offset) \
121 bool holder::name() { \
122 return BooleanBit::get(field(), offset); \
123 } \
124
125
126#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000127 bool holder::name() { \
128 return BooleanBit::get(field(), offset); \
129 } \
130 void holder::set_##name(bool value) { \
131 set_##field(BooleanBit::set(field(), offset, value)); \
132 }
133
134
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000135bool Object::IsFixedArrayBase() {
136 return IsFixedArray() || IsFixedDoubleArray();
137}
138
139
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000140// External objects are not extensible, so the map check is enough.
141bool Object::IsExternal() {
142 return Object::IsHeapObject() &&
143 HeapObject::cast(this)->map() ==
144 HeapObject::cast(this)->GetHeap()->external_map();
145}
146
147
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000148bool Object::IsAccessorInfo() {
149 return IsExecutableAccessorInfo() || IsDeclaredAccessorInfo();
150}
151
152
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000153bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
154 // There is a constraint on the object; check.
155 if (!this->IsJSObject()) return false;
156 // Fetch the constructor function of the object.
157 Object* cons_obj = JSObject::cast(this)->map()->constructor();
158 if (!cons_obj->IsJSFunction()) return false;
159 JSFunction* fun = JSFunction::cast(cons_obj);
160 // Iterate through the chain of inheriting function templates to
161 // see if the required one occurs.
162 for (Object* type = fun->shared()->function_data();
163 type->IsFunctionTemplateInfo();
164 type = FunctionTemplateInfo::cast(type)->parent_template()) {
165 if (type == expected) return true;
166 }
167 // Didn't find the required type in the inheritance chain.
168 return false;
169}
170
171
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000172bool Object::IsSmi() {
173 return HAS_SMI_TAG(this);
174}
175
176
177bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000178 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000179}
180
181
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000182bool Object::NonFailureIsHeapObject() {
183 ASSERT(!this->IsFailure());
184 return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0;
185}
186
187
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000188TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000189TYPE_CHECKER(Symbol, SYMBOL_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000190
191
192bool Object::IsString() {
193 return Object::IsHeapObject()
194 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
195}
196
197
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000198bool Object::IsName() {
199 return IsString() || IsSymbol();
200}
201
202
203bool Object::IsUniqueName() {
204 return IsInternalizedString() || IsSymbol();
205}
206
207
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000208bool Object::IsSpecObject() {
209 return Object::IsHeapObject()
210 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
211}
212
213
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000214bool Object::IsSpecFunction() {
215 if (!Object::IsHeapObject()) return false;
216 InstanceType type = HeapObject::cast(this)->map()->instance_type();
217 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
218}
219
220
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000221bool Object::IsInternalizedString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000222 if (!this->IsHeapObject()) return false;
223 uint32_t type = HeapObject::cast(this)->map()->instance_type();
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000224 STATIC_ASSERT(kInternalizedTag != 0);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000225 return (type & (kIsNotStringMask | kIsInternalizedMask)) ==
226 (kInternalizedTag | kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000227}
228
229
230bool Object::IsConsString() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000231 if (!IsString()) return false;
232 return StringShape(String::cast(this)).IsCons();
233}
234
235
236bool Object::IsSlicedString() {
237 if (!IsString()) return false;
238 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000239}
240
241
ager@chromium.org870a0b62008-11-04 11:43:05 +0000242bool Object::IsSeqString() {
243 if (!IsString()) return false;
244 return StringShape(String::cast(this)).IsSequential();
245}
246
247
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000248bool Object::IsSeqOneByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000249 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000250 return StringShape(String::cast(this)).IsSequential() &&
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000251 String::cast(this)->IsOneByteRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000252}
253
254
255bool Object::IsSeqTwoByteString() {
256 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000257 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000258 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000259}
260
261
262bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000263 if (!IsString()) return false;
264 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000265}
266
267
268bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000269 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000270 return StringShape(String::cast(this)).IsExternal() &&
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000271 String::cast(this)->IsOneByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000272}
273
274
275bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000276 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000277 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000278 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000279}
280
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000281bool Object::HasValidElements() {
282 // Dictionary is covered under FixedArray.
283 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
284}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000285
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000286
287MaybeObject* Object::AllocateNewStorageFor(Heap* heap,
288 Representation representation,
289 PretenureFlag tenure) {
290 if (!FLAG_track_double_fields) return this;
291 if (!representation.IsDouble()) return this;
danno@chromium.org1fd77d52013-06-07 16:01:45 +0000292 if (IsUninitialized()) {
293 return heap->AllocateHeapNumber(0, tenure);
294 }
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000295 return heap->AllocateHeapNumber(Number(), tenure);
296}
297
298
ager@chromium.org870a0b62008-11-04 11:43:05 +0000299StringShape::StringShape(String* str)
300 : type_(str->map()->instance_type()) {
301 set_valid();
302 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000303}
304
305
ager@chromium.org870a0b62008-11-04 11:43:05 +0000306StringShape::StringShape(Map* map)
307 : type_(map->instance_type()) {
308 set_valid();
309 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000310}
311
312
ager@chromium.org870a0b62008-11-04 11:43:05 +0000313StringShape::StringShape(InstanceType t)
314 : type_(static_cast<uint32_t>(t)) {
315 set_valid();
316 ASSERT((type_ & kIsNotStringMask) == kStringTag);
317}
318
319
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000320bool StringShape::IsInternalized() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000321 ASSERT(valid());
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000322 STATIC_ASSERT(kInternalizedTag != 0);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000323 return (type_ & (kIsNotStringMask | kIsInternalizedMask)) ==
324 (kInternalizedTag | kStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000325}
326
327
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000328bool String::IsOneByteRepresentation() {
ager@chromium.org5ec48922009-05-05 07:25:34 +0000329 uint32_t type = map()->instance_type();
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000330 return (type & kStringEncodingMask) == kOneByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000331}
332
333
ager@chromium.org5ec48922009-05-05 07:25:34 +0000334bool String::IsTwoByteRepresentation() {
335 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000336 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000337}
338
339
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000340bool String::IsOneByteRepresentationUnderneath() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000341 uint32_t type = map()->instance_type();
342 STATIC_ASSERT(kIsIndirectStringTag != 0);
343 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
344 ASSERT(IsFlat());
345 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000346 case kOneByteStringTag:
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000347 return true;
348 case kTwoByteStringTag:
349 return false;
350 default: // Cons or sliced string. Need to go deeper.
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000351 return GetUnderlying()->IsOneByteRepresentation();
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000352 }
353}
354
355
356bool String::IsTwoByteRepresentationUnderneath() {
357 uint32_t type = map()->instance_type();
358 STATIC_ASSERT(kIsIndirectStringTag != 0);
359 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
360 ASSERT(IsFlat());
361 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000362 case kOneByteStringTag:
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000363 return false;
364 case kTwoByteStringTag:
365 return true;
366 default: // Cons or sliced string. Need to go deeper.
367 return GetUnderlying()->IsTwoByteRepresentation();
368 }
369}
370
371
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000372bool String::HasOnlyOneByteChars() {
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000373 uint32_t type = map()->instance_type();
danno@chromium.orgf005df62013-04-30 16:36:45 +0000374 return (type & kOneByteDataHintMask) == kOneByteDataHintTag ||
375 IsOneByteRepresentation();
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000376}
377
378
ager@chromium.org870a0b62008-11-04 11:43:05 +0000379bool StringShape::IsCons() {
380 return (type_ & kStringRepresentationMask) == kConsStringTag;
381}
382
383
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000384bool StringShape::IsSliced() {
385 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
386}
387
388
389bool StringShape::IsIndirect() {
390 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
391}
392
393
ager@chromium.org870a0b62008-11-04 11:43:05 +0000394bool StringShape::IsExternal() {
395 return (type_ & kStringRepresentationMask) == kExternalStringTag;
396}
397
398
399bool StringShape::IsSequential() {
400 return (type_ & kStringRepresentationMask) == kSeqStringTag;
401}
402
403
404StringRepresentationTag StringShape::representation_tag() {
405 uint32_t tag = (type_ & kStringRepresentationMask);
406 return static_cast<StringRepresentationTag>(tag);
407}
408
409
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000410uint32_t StringShape::encoding_tag() {
411 return type_ & kStringEncodingMask;
412}
413
414
ager@chromium.org870a0b62008-11-04 11:43:05 +0000415uint32_t StringShape::full_representation_tag() {
416 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
417}
418
419
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000420STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
421 Internals::kFullStringRepresentationMask);
422
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000423STATIC_CHECK(static_cast<uint32_t>(kStringEncodingMask) ==
424 Internals::kStringEncodingMask);
425
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000426
ager@chromium.org870a0b62008-11-04 11:43:05 +0000427bool StringShape::IsSequentialAscii() {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000428 return full_representation_tag() == (kSeqStringTag | kOneByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000429}
430
431
432bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000433 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000434}
435
436
437bool StringShape::IsExternalAscii() {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000438 return full_representation_tag() == (kExternalStringTag | kOneByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000439}
440
441
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000442STATIC_CHECK((kExternalStringTag | kOneByteStringTag) ==
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000443 Internals::kExternalAsciiRepresentationTag);
444
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000445STATIC_CHECK(v8::String::ASCII_ENCODING == kOneByteStringTag);
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000446
447
ager@chromium.org870a0b62008-11-04 11:43:05 +0000448bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000449 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000450}
451
452
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000453STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
454 Internals::kExternalTwoByteRepresentationTag);
455
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000456STATIC_CHECK(v8::String::TWO_BYTE_ENCODING == kTwoByteStringTag);
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000457
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000458uc32 FlatStringReader::Get(int index) {
459 ASSERT(0 <= index && index <= length_);
460 if (is_ascii_) {
461 return static_cast<const byte*>(start_)[index];
462 } else {
463 return static_cast<const uc16*>(start_)[index];
464 }
465}
466
467
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000468bool Object::IsNumber() {
469 return IsSmi() || IsHeapNumber();
470}
471
472
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000473TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
474TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000475
476
477bool Object::IsFiller() {
478 if (!Object::IsHeapObject()) return false;
479 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
480 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
481}
482
483
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000484TYPE_CHECKER(ExternalPixelArray, EXTERNAL_PIXEL_ARRAY_TYPE)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000485
486
ager@chromium.org3811b432009-10-28 14:53:37 +0000487bool Object::IsExternalArray() {
488 if (!Object::IsHeapObject())
489 return false;
490 InstanceType instance_type =
491 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000492 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
493 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000494}
495
496
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000497TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE)
498TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
499TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE)
500TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
501TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE)
502TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
503TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE)
504TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000505
506
lrn@chromium.org303ada72010-10-27 09:33:13 +0000507bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000508 return HAS_FAILURE_TAG(this);
509}
510
511
lrn@chromium.org303ada72010-10-27 09:33:13 +0000512bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000513 return HAS_FAILURE_TAG(this)
514 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
515}
516
517
lrn@chromium.org303ada72010-10-27 09:33:13 +0000518bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000519 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000520 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000521}
522
523
lrn@chromium.org303ada72010-10-27 09:33:13 +0000524bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000525 return this == Failure::Exception();
526}
527
528
lrn@chromium.org303ada72010-10-27 09:33:13 +0000529bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000530 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000531}
532
533
danno@chromium.org1fd77d52013-06-07 16:01:45 +0000534bool MaybeObject::IsUninitialized() {
535 return !IsFailure() && ToObjectUnchecked()->IsUninitialized();
536}
537
538
lrn@chromium.org303ada72010-10-27 09:33:13 +0000539Failure* Failure::cast(MaybeObject* obj) {
540 ASSERT(HAS_FAILURE_TAG(obj));
541 return reinterpret_cast<Failure*>(obj);
542}
543
544
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000545bool Object::IsJSReceiver() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000546 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000547 return IsHeapObject() &&
548 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
549}
550
551
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000552bool Object::IsJSObject() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000553 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
554 return IsHeapObject() &&
555 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000556}
557
558
559bool Object::IsJSProxy() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000560 if (!Object::IsHeapObject()) return false;
561 InstanceType type = HeapObject::cast(this)->map()->instance_type();
562 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000563}
564
565
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000566TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
567TYPE_CHECKER(JSSet, JS_SET_TYPE)
568TYPE_CHECKER(JSMap, JS_MAP_TYPE)
569TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
570TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
571TYPE_CHECKER(Map, MAP_TYPE)
572TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
573TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000574
575
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000576bool Object::IsDescriptorArray() {
577 return IsFixedArray();
578}
579
580
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000581bool Object::IsTransitionArray() {
582 return IsFixedArray();
583}
584
585
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000586bool Object::IsDeoptimizationInputData() {
587 // Must be a fixed array.
588 if (!IsFixedArray()) return false;
589
590 // There's no sure way to detect the difference between a fixed array and
591 // a deoptimization data array. Since this is used for asserts we can
592 // check that the length is zero or else the fixed size plus a multiple of
593 // the entry size.
594 int length = FixedArray::cast(this)->length();
595 if (length == 0) return true;
596
597 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
598 return length >= 0 &&
599 length % DeoptimizationInputData::kDeoptEntrySize == 0;
600}
601
602
603bool Object::IsDeoptimizationOutputData() {
604 if (!IsFixedArray()) return false;
605 // There's actually no way to see the difference between a fixed array and
606 // a deoptimization data array. Since this is used for asserts we can check
607 // that the length is plausible though.
608 if (FixedArray::cast(this)->length() % 2 != 0) return false;
609 return true;
610}
611
612
ulan@chromium.org2e04b582013-02-21 14:06:02 +0000613bool Object::IsDependentCode() {
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000614 if (!IsFixedArray()) return false;
615 // There's actually no way to see the difference between a fixed array and
616 // a dependent codes array.
617 return true;
618}
619
620
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000621bool Object::IsTypeFeedbackCells() {
622 if (!IsFixedArray()) return false;
623 // There's actually no way to see the difference between a fixed array and
624 // a cache cells array. Since this is used for asserts we can check that
625 // the length is plausible though.
626 if (FixedArray::cast(this)->length() % 2 != 0) return false;
627 return true;
628}
629
630
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000631bool Object::IsContext() {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000632 if (!Object::IsHeapObject()) return false;
633 Map* map = HeapObject::cast(this)->map();
634 Heap* heap = map->GetHeap();
635 return (map == heap->function_context_map() ||
636 map == heap->catch_context_map() ||
637 map == heap->with_context_map() ||
638 map == heap->native_context_map() ||
639 map == heap->block_context_map() ||
640 map == heap->module_context_map() ||
641 map == heap->global_context_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000642}
643
644
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000645bool Object::IsNativeContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000646 return Object::IsHeapObject() &&
647 HeapObject::cast(this)->map() ==
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000648 HeapObject::cast(this)->GetHeap()->native_context_map();
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000649}
650
651
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000652bool Object::IsScopeInfo() {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000653 return Object::IsHeapObject() &&
654 HeapObject::cast(this)->map() ==
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000655 HeapObject::cast(this)->GetHeap()->scope_info_map();
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000656}
657
658
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000659TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000660
661
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000662template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000663 return obj->IsJSFunction();
664}
665
666
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000667TYPE_CHECKER(Code, CODE_TYPE)
668TYPE_CHECKER(Oddball, ODDBALL_TYPE)
danno@chromium.org41728482013-06-12 22:31:22 +0000669TYPE_CHECKER(Cell, CELL_TYPE)
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000670TYPE_CHECKER(PropertyCell, PROPERTY_CELL_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000671TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000672TYPE_CHECKER(JSGeneratorObject, JS_GENERATOR_OBJECT_TYPE)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +0000673TYPE_CHECKER(JSModule, JS_MODULE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000674TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000675TYPE_CHECKER(JSDate, JS_DATE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000676TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000677
678
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000679bool Object::IsStringWrapper() {
680 return IsJSValue() && JSValue::cast(this)->value()->IsString();
681}
682
683
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000684TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000685
686
687bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000688 return IsOddball() &&
689 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000690}
691
692
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000693TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000694TYPE_CHECKER(JSArrayBuffer, JS_ARRAY_BUFFER_TYPE)
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000695TYPE_CHECKER(JSTypedArray, JS_TYPED_ARRAY_TYPE)
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000696TYPE_CHECKER(JSDataView, JS_DATA_VIEW_TYPE)
697
698
699bool Object::IsJSArrayBufferView() {
700 return IsJSDataView() || IsJSTypedArray();
701}
702
703
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000704TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000705
706
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000707template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000708 return obj->IsJSArray();
709}
710
711
712bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000713 return Object::IsHeapObject() &&
714 HeapObject::cast(this)->map() ==
715 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000716}
717
718
719bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000720 return IsHashTable() &&
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000721 this != HeapObject::cast(this)->GetHeap()->string_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000722}
723
724
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000725bool Object::IsStringTable() {
danno@chromium.org72204d52012-10-31 10:02:10 +0000726 return IsHashTable() &&
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000727 this == HeapObject::cast(this)->GetHeap()->raw_unchecked_string_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000728}
729
730
ager@chromium.orgac091b72010-05-05 07:34:42 +0000731bool Object::IsJSFunctionResultCache() {
732 if (!IsFixedArray()) return false;
733 FixedArray* self = FixedArray::cast(this);
734 int length = self->length();
735 if (length < JSFunctionResultCache::kEntriesIndex) return false;
736 if ((length - JSFunctionResultCache::kEntriesIndex)
737 % JSFunctionResultCache::kEntrySize != 0) {
738 return false;
739 }
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +0000740#ifdef VERIFY_HEAP
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000741 if (FLAG_verify_heap) {
742 reinterpret_cast<JSFunctionResultCache*>(this)->
743 JSFunctionResultCacheVerify();
744 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000745#endif
746 return true;
747}
748
749
ricow@chromium.org65fae842010-08-25 15:26:24 +0000750bool Object::IsNormalizedMapCache() {
751 if (!IsFixedArray()) return false;
752 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
753 return false;
754 }
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +0000755#ifdef VERIFY_HEAP
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000756 if (FLAG_verify_heap) {
757 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
758 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000759#endif
760 return true;
761}
762
763
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000764bool Object::IsCompilationCacheTable() {
765 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000766}
767
768
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000769bool Object::IsCodeCacheHashTable() {
770 return IsHashTable();
771}
772
773
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000774bool Object::IsPolymorphicCodeCacheHashTable() {
775 return IsHashTable();
776}
777
778
ager@chromium.org236ad962008-09-25 09:45:57 +0000779bool Object::IsMapCache() {
780 return IsHashTable();
781}
782
783
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000784bool Object::IsObjectHashTable() {
785 return IsHashTable();
786}
787
788
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000789bool Object::IsPrimitive() {
790 return IsOddball() || IsNumber() || IsString();
791}
792
793
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000794bool Object::IsJSGlobalProxy() {
795 bool result = IsHeapObject() &&
796 (HeapObject::cast(this)->map()->instance_type() ==
797 JS_GLOBAL_PROXY_TYPE);
798 ASSERT(!result || IsAccessCheckNeeded());
799 return result;
800}
801
802
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000803bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000804 if (!IsHeapObject()) return false;
805
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000806 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000807 return type == JS_GLOBAL_OBJECT_TYPE ||
808 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000809}
810
811
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000812TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
813TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000814
815
816bool Object::IsUndetectableObject() {
817 return IsHeapObject()
818 && HeapObject::cast(this)->map()->is_undetectable();
819}
820
821
822bool Object::IsAccessCheckNeeded() {
823 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000824 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000825}
826
827
828bool Object::IsStruct() {
829 if (!IsHeapObject()) return false;
830 switch (HeapObject::cast(this)->map()->instance_type()) {
831#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
832 STRUCT_LIST(MAKE_STRUCT_CASE)
833#undef MAKE_STRUCT_CASE
834 default: return false;
835 }
836}
837
838
839#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
840 bool Object::Is##Name() { \
841 return Object::IsHeapObject() \
842 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
843 }
844 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
845#undef MAKE_STRUCT_PREDICATE
846
847
848bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000849 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000850}
851
852
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000853bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000854 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
855}
856
857
858bool Object::IsTheHole() {
859 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000860}
861
862
danno@chromium.org1fd77d52013-06-07 16:01:45 +0000863bool Object::IsUninitialized() {
864 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUninitialized;
865}
866
867
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000868bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000869 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000870}
871
872
873bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000874 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000875}
876
877
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000878bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000879 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000880}
881
882
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000883double Object::Number() {
884 ASSERT(IsNumber());
885 return IsSmi()
886 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
887 : reinterpret_cast<HeapNumber*>(this)->value();
888}
889
890
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000891bool Object::IsNaN() {
ulan@chromium.org77ca49a2013-04-22 09:43:56 +0000892 return this->IsHeapNumber() && std::isnan(HeapNumber::cast(this)->value());
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000893}
894
895
lrn@chromium.org303ada72010-10-27 09:33:13 +0000896MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000897 if (IsSmi()) return this;
898 if (IsHeapNumber()) {
899 double value = HeapNumber::cast(this)->value();
900 int int_value = FastD2I(value);
901 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
902 return Smi::FromInt(int_value);
903 }
904 }
905 return Failure::Exception();
906}
907
908
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000909bool Object::HasSpecificClassOf(String* name) {
910 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
911}
912
913
lrn@chromium.org303ada72010-10-27 09:33:13 +0000914MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000915 // GetElement can trigger a getter which can cause allocation.
916 // This was not always the case. This ASSERT is here to catch
917 // leftover incorrect uses.
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000918 ASSERT(AllowHeapAllocation::IsAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000919 return GetElementWithReceiver(this, index);
920}
921
922
lrn@chromium.org303ada72010-10-27 09:33:13 +0000923Object* Object::GetElementNoExceptionThrown(uint32_t index) {
924 MaybeObject* maybe = GetElementWithReceiver(this, index);
925 ASSERT(!maybe->IsFailure());
926 Object* result = NULL; // Initialization to please compiler.
927 maybe->ToObject(&result);
928 return result;
929}
930
931
ulan@chromium.org750145a2013-03-07 15:14:13 +0000932MaybeObject* Object::GetProperty(Name* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000933 PropertyAttributes attributes;
934 return GetPropertyWithReceiver(this, key, &attributes);
935}
936
937
ulan@chromium.org750145a2013-03-07 15:14:13 +0000938MaybeObject* Object::GetProperty(Name* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000939 return GetPropertyWithReceiver(this, key, attributes);
940}
941
942
943#define FIELD_ADDR(p, offset) \
944 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
945
946#define READ_FIELD(p, offset) \
947 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
948
949#define WRITE_FIELD(p, offset, value) \
950 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
951
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000952#define WRITE_BARRIER(heap, object, offset, value) \
953 heap->incremental_marking()->RecordWrite( \
954 object, HeapObject::RawField(object, offset), value); \
955 if (heap->InNewSpace(value)) { \
956 heap->RecordWrite(object->address(), offset); \
957 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000958
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000959#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
960 if (mode == UPDATE_WRITE_BARRIER) { \
961 heap->incremental_marking()->RecordWrite( \
962 object, HeapObject::RawField(object, offset), value); \
963 if (heap->InNewSpace(value)) { \
964 heap->RecordWrite(object->address(), offset); \
965 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000966 }
967
lrn@chromium.org7516f052011-03-30 08:52:27 +0000968#ifndef V8_TARGET_ARCH_MIPS
969 #define READ_DOUBLE_FIELD(p, offset) \
970 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
971#else // V8_TARGET_ARCH_MIPS
972 // Prevent gcc from using load-double (mips ldc1) on (possibly)
973 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000974 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000975 union conversion {
976 double d;
977 uint32_t u[2];
978 } c;
979 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
980 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
981 return c.d;
982 }
983 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
984#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000985
lrn@chromium.org7516f052011-03-30 08:52:27 +0000986#ifndef V8_TARGET_ARCH_MIPS
987 #define WRITE_DOUBLE_FIELD(p, offset, value) \
988 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
989#else // V8_TARGET_ARCH_MIPS
990 // Prevent gcc from using store-double (mips sdc1) on (possibly)
991 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000992 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000993 double value) {
994 union conversion {
995 double d;
996 uint32_t u[2];
997 } c;
998 c.d = value;
999 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
1000 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
1001 }
1002 #define WRITE_DOUBLE_FIELD(p, offset, value) \
1003 write_double_field(p, offset, value)
1004#endif // V8_TARGET_ARCH_MIPS
1005
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001006
1007#define READ_INT_FIELD(p, offset) \
1008 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
1009
1010#define WRITE_INT_FIELD(p, offset, value) \
1011 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
1012
ager@chromium.org3e875802009-06-29 08:26:34 +00001013#define READ_INTPTR_FIELD(p, offset) \
1014 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
1015
1016#define WRITE_INTPTR_FIELD(p, offset, value) \
1017 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
1018
ager@chromium.org7c537e22008-10-16 08:43:32 +00001019#define READ_UINT32_FIELD(p, offset) \
1020 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
1021
1022#define WRITE_UINT32_FIELD(p, offset, value) \
1023 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
1024
danno@chromium.org88aa0582012-03-23 15:11:57 +00001025#define READ_INT64_FIELD(p, offset) \
1026 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)))
1027
1028#define WRITE_INT64_FIELD(p, offset, value) \
1029 (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
1030
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001031#define READ_SHORT_FIELD(p, offset) \
1032 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
1033
1034#define WRITE_SHORT_FIELD(p, offset, value) \
1035 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
1036
1037#define READ_BYTE_FIELD(p, offset) \
1038 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
1039
1040#define WRITE_BYTE_FIELD(p, offset, value) \
1041 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
1042
1043
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +00001044Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
1045 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001046}
1047
1048
1049int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +00001050 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001051}
1052
1053
1054Smi* Smi::FromInt(int value) {
1055 ASSERT(Smi::IsValid(value));
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001056 return reinterpret_cast<Smi*>(Internals::IntToSmi(value));
ager@chromium.org9085a012009-05-11 19:22:57 +00001057}
1058
1059
1060Smi* Smi::FromIntptr(intptr_t value) {
1061 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001062 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
1063 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001064}
1065
1066
1067Failure::Type Failure::type() const {
1068 return static_cast<Type>(value() & kFailureTypeTagMask);
1069}
1070
1071
1072bool Failure::IsInternalError() const {
1073 return type() == INTERNAL_ERROR;
1074}
1075
1076
1077bool Failure::IsOutOfMemoryException() const {
1078 return type() == OUT_OF_MEMORY_EXCEPTION;
1079}
1080
1081
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001082AllocationSpace Failure::allocation_space() const {
1083 ASSERT_EQ(RETRY_AFTER_GC, type());
1084 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1085 & kSpaceTagMask);
1086}
1087
1088
1089Failure* Failure::InternalError() {
1090 return Construct(INTERNAL_ERROR);
1091}
1092
1093
1094Failure* Failure::Exception() {
1095 return Construct(EXCEPTION);
1096}
1097
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001098
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00001099Failure* Failure::OutOfMemoryException(intptr_t value) {
1100 return Construct(OUT_OF_MEMORY_EXCEPTION, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001101}
1102
1103
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001104intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001105 return static_cast<intptr_t>(
1106 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001107}
1108
1109
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001110Failure* Failure::RetryAfterGC() {
1111 return RetryAfterGC(NEW_SPACE);
1112}
1113
1114
1115Failure* Failure::RetryAfterGC(AllocationSpace space) {
1116 ASSERT((space & ~kSpaceTagMask) == 0);
1117 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001118}
1119
1120
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001121Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001122 uintptr_t info =
1123 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001124 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
jkummerow@chromium.org5323a9c2012-12-10 19:00:50 +00001125 // Fill the unused bits with a pattern that's easy to recognize in crash
1126 // dumps.
1127 static const int kFailureMagicPattern = 0x0BAD0000;
1128 return reinterpret_cast<Failure*>(
1129 (info << kFailureTagSize) | kFailureTag | kFailureMagicPattern);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001130}
1131
1132
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001133bool Smi::IsValid(intptr_t value) {
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001134 bool result = Internals::IsValidSmi(value);
1135 ASSERT_EQ(result, value >= kMinValue && value <= kMaxValue);
ager@chromium.org9085a012009-05-11 19:22:57 +00001136 return result;
1137}
1138
1139
kasper.lund7276f142008-07-30 08:49:36 +00001140MapWord MapWord::FromMap(Map* map) {
1141 return MapWord(reinterpret_cast<uintptr_t>(map));
1142}
1143
1144
1145Map* MapWord::ToMap() {
1146 return reinterpret_cast<Map*>(value_);
1147}
1148
1149
1150bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001151 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001152}
1153
1154
1155MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001156 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1157 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001158}
1159
1160
1161HeapObject* MapWord::ToForwardingAddress() {
1162 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001163 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001164}
1165
1166
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00001167#ifdef VERIFY_HEAP
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001168void HeapObject::VerifyObjectField(int offset) {
1169 VerifyPointer(READ_FIELD(this, offset));
1170}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001171
1172void HeapObject::VerifySmiField(int offset) {
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00001173 CHECK(READ_FIELD(this, offset)->IsSmi());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001174}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001175#endif
1176
1177
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001178Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001179 Heap* heap =
1180 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1181 ASSERT(heap != NULL);
1182 ASSERT(heap->isolate() == Isolate::Current());
1183 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001184}
1185
1186
1187Isolate* HeapObject::GetIsolate() {
1188 return GetHeap()->isolate();
1189}
1190
1191
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001192Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001193 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001194}
1195
1196
1197void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001198 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001199 if (value != NULL) {
1200 // TODO(1600) We are passing NULL as a slot because maps can never be on
1201 // evacuation candidate.
1202 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1203 }
1204}
1205
1206
1207// Unsafe accessor omitting write barrier.
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001208void HeapObject::set_map_no_write_barrier(Map* value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001209 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001210}
1211
1212
kasper.lund7276f142008-07-30 08:49:36 +00001213MapWord HeapObject::map_word() {
1214 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1215}
1216
1217
1218void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001219 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001220 // here.
1221 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1222}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001223
1224
1225HeapObject* HeapObject::FromAddress(Address address) {
1226 ASSERT_TAG_ALIGNED(address);
1227 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1228}
1229
1230
1231Address HeapObject::address() {
1232 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1233}
1234
1235
1236int HeapObject::Size() {
1237 return SizeFromMap(map());
1238}
1239
1240
1241void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1242 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1243 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1244}
1245
1246
1247void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1248 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1249}
1250
1251
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001252double HeapNumber::value() {
1253 return READ_DOUBLE_FIELD(this, kValueOffset);
1254}
1255
1256
1257void HeapNumber::set_value(double value) {
1258 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1259}
1260
1261
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001262int HeapNumber::get_exponent() {
1263 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1264 kExponentShift) - kExponentBias;
1265}
1266
1267
1268int HeapNumber::get_sign() {
1269 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1270}
1271
1272
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001273ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001274
1275
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001276Object** FixedArray::GetFirstElementAddress() {
1277 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1278}
1279
1280
1281bool FixedArray::ContainsOnlySmisOrHoles() {
1282 Object* the_hole = GetHeap()->the_hole_value();
1283 Object** current = GetFirstElementAddress();
1284 for (int i = 0; i < length(); ++i) {
1285 Object* candidate = *current++;
1286 if (!candidate->IsSmi() && candidate != the_hole) return false;
1287 }
1288 return true;
1289}
1290
1291
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001292FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001293 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001294 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001295}
1296
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001297
1298void JSObject::ValidateElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001299#if DEBUG
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001300 if (FLAG_enable_slow_asserts) {
1301 ElementsAccessor* accessor = GetElementsAccessor();
1302 accessor->Validate(this);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001303 }
1304#endif
1305}
1306
1307
danno@chromium.orgca29dd82013-04-26 11:59:48 +00001308bool JSObject::ShouldTrackAllocationInfo() {
1309 if (map()->CanTrackAllocationSite()) {
1310 if (!IsJSArray()) {
1311 return true;
1312 }
1313
1314 return AllocationSiteInfo::GetMode(GetElementsKind()) ==
1315 TRACK_ALLOCATION_SITE;
1316 }
1317 return false;
1318}
1319
1320
1321// Heuristic: We only need to create allocation site info if the boilerplate
1322// elements kind is the initial elements kind.
1323AllocationSiteMode AllocationSiteInfo::GetMode(
1324 ElementsKind boilerplate_elements_kind) {
1325 if (FLAG_track_allocation_sites &&
1326 IsFastSmiElementsKind(boilerplate_elements_kind)) {
1327 return TRACK_ALLOCATION_SITE;
1328 }
1329
1330 return DONT_TRACK_ALLOCATION_SITE;
1331}
1332
1333
1334AllocationSiteMode AllocationSiteInfo::GetMode(ElementsKind from,
1335 ElementsKind to) {
1336 if (FLAG_track_allocation_sites &&
1337 IsFastSmiElementsKind(from) &&
1338 (IsFastObjectElementsKind(to) || IsFastDoubleElementsKind(to))) {
1339 return TRACK_ALLOCATION_SITE;
1340 }
1341
1342 return DONT_TRACK_ALLOCATION_SITE;
1343}
1344
1345
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001346MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001347 ValidateElements();
1348 ElementsKind elements_kind = map()->elements_kind();
1349 if (!IsFastObjectElementsKind(elements_kind)) {
1350 if (IsFastHoleyElementsKind(elements_kind)) {
1351 return TransitionElementsKind(FAST_HOLEY_ELEMENTS);
1352 } else {
1353 return TransitionElementsKind(FAST_ELEMENTS);
1354 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001355 }
1356 return this;
1357}
1358
1359
1360MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001361 uint32_t count,
1362 EnsureElementsMode mode) {
1363 ElementsKind current_kind = map()->elements_kind();
1364 ElementsKind target_kind = current_kind;
1365 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001366 bool is_holey = IsFastHoleyElementsKind(current_kind);
1367 if (current_kind == FAST_HOLEY_ELEMENTS) return this;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001368 Heap* heap = GetHeap();
1369 Object* the_hole = heap->the_hole_value();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001370 for (uint32_t i = 0; i < count; ++i) {
1371 Object* current = *objects++;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001372 if (current == the_hole) {
1373 is_holey = true;
1374 target_kind = GetHoleyElementsKind(target_kind);
1375 } else if (!current->IsSmi()) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001376 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && current->IsNumber()) {
1377 if (IsFastSmiElementsKind(target_kind)) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001378 if (is_holey) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001379 target_kind = FAST_HOLEY_DOUBLE_ELEMENTS;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001380 } else {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001381 target_kind = FAST_DOUBLE_ELEMENTS;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001382 }
1383 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001384 } else if (is_holey) {
1385 target_kind = FAST_HOLEY_ELEMENTS;
1386 break;
1387 } else {
1388 target_kind = FAST_ELEMENTS;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001389 }
1390 }
1391 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001392
1393 if (target_kind != current_kind) {
1394 return TransitionElementsKind(target_kind);
1395 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001396 return this;
1397}
1398
1399
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001400MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001401 uint32_t length,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001402 EnsureElementsMode mode) {
1403 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1404 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1405 elements->map() == GetHeap()->fixed_cow_array_map());
1406 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1407 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1408 }
1409 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001410 return EnsureCanContainElements(objects, length, mode);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001411 }
1412
1413 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001414 if (GetElementsKind() == FAST_HOLEY_SMI_ELEMENTS) {
1415 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS);
1416 } else if (GetElementsKind() == FAST_SMI_ELEMENTS) {
1417 FixedDoubleArray* double_array = FixedDoubleArray::cast(elements);
1418 for (uint32_t i = 0; i < length; ++i) {
1419 if (double_array->is_the_hole(i)) {
1420 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS);
1421 }
1422 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001423 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1424 }
1425
1426 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001427}
1428
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001429
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001430MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
1431 ElementsKind to_kind) {
1432 Map* current_map = map();
1433 ElementsKind from_kind = current_map->elements_kind();
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001434 if (from_kind == to_kind) return current_map;
1435
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001436 Context* native_context = isolate->context()->native_context();
1437 Object* maybe_array_maps = native_context->js_array_maps();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001438 if (maybe_array_maps->IsFixedArray()) {
1439 FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
1440 if (array_maps->get(from_kind) == current_map) {
1441 Object* maybe_transitioned_map = array_maps->get(to_kind);
1442 if (maybe_transitioned_map->IsMap()) {
1443 return Map::cast(maybe_transitioned_map);
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001444 }
1445 }
1446 }
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001447
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001448 return GetElementsTransitionMapSlow(to_kind);
1449}
1450
1451
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001452void JSObject::set_map_and_elements(Map* new_map,
1453 FixedArrayBase* value,
1454 WriteBarrierMode mode) {
1455 ASSERT(value->HasValidElements());
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001456 if (new_map != NULL) {
1457 if (mode == UPDATE_WRITE_BARRIER) {
1458 set_map(new_map);
1459 } else {
1460 ASSERT(mode == SKIP_WRITE_BARRIER);
1461 set_map_no_write_barrier(new_map);
1462 }
1463 }
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001464 ASSERT((map()->has_fast_smi_or_object_elements() ||
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001465 (value == GetHeap()->empty_fixed_array())) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001466 (value->map() == GetHeap()->fixed_array_map() ||
1467 value->map() == GetHeap()->fixed_cow_array_map()));
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001468 ASSERT((value == GetHeap()->empty_fixed_array()) ||
1469 (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001470 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001471 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001472}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001473
1474
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001475void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1476 set_map_and_elements(NULL, value, mode);
1477}
1478
1479
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001480void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001481 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1482 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001483}
1484
1485
1486void JSObject::initialize_elements() {
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +00001487 if (map()->has_fast_smi_or_object_elements() ||
1488 map()->has_fast_double_elements()) {
1489 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1490 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
1491 } else if (map()->has_external_array_elements()) {
1492 ExternalArray* empty_array = GetHeap()->EmptyExternalArrayForMap(map());
1493 ASSERT(!GetHeap()->InNewSpace(empty_array));
1494 WRITE_FIELD(this, kElementsOffset, empty_array);
1495 } else {
1496 UNREACHABLE();
1497 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001498}
1499
1500
lrn@chromium.org303ada72010-10-27 09:33:13 +00001501MaybeObject* JSObject::ResetElements() {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001502 if (map()->is_observed()) {
1503 // Maintain invariant that observed elements are always in dictionary mode.
1504 SeededNumberDictionary* dictionary;
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001505 MaybeObject* maybe = SeededNumberDictionary::Allocate(GetHeap(), 0);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001506 if (!maybe->To(&dictionary)) return maybe;
1507 if (map() == GetHeap()->non_strict_arguments_elements_map()) {
1508 FixedArray::cast(elements())->set(1, dictionary);
1509 } else {
1510 set_elements(dictionary);
1511 }
1512 return this;
1513 }
1514
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001515 ElementsKind elements_kind = GetInitialFastElementsKind();
1516 if (!FLAG_smi_only_arrays) {
1517 elements_kind = FastSmiToObjectElementsKind(elements_kind);
1518 }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001519 MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind);
1520 Map* map;
1521 if (!maybe->To(&map)) return maybe;
1522 set_map(map);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001523 initialize_elements();
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001524
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001525 return this;
1526}
1527
1528
ulan@chromium.org57ff8812013-05-10 08:16:55 +00001529MaybeObject* JSObject::AllocateStorageForMap(Map* map) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001530 ASSERT(this->map()->inobject_properties() == map->inobject_properties());
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +00001531 ElementsKind obj_kind = this->map()->elements_kind();
1532 ElementsKind map_kind = map->elements_kind();
1533 if (map_kind != obj_kind) {
1534 ElementsKind to_kind = map_kind;
1535 if (IsMoreGeneralElementsKindTransition(map_kind, obj_kind) ||
1536 IsDictionaryElementsKind(obj_kind)) {
1537 to_kind = obj_kind;
1538 }
1539 MaybeObject* maybe_obj =
1540 IsDictionaryElementsKind(to_kind) ? NormalizeElements()
1541 : TransitionElementsKind(to_kind);
1542 if (maybe_obj->IsFailure()) return maybe_obj;
1543 MaybeObject* maybe_map = map->AsElementsKind(to_kind);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001544 if (!maybe_map->To(&map)) return maybe_map;
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001545 }
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001546 int total_size =
1547 map->NumberOfOwnDescriptors() + map->unused_property_fields();
1548 int out_of_object = total_size - map->inobject_properties();
1549 if (out_of_object != properties()->length()) {
1550 FixedArray* new_properties;
1551 MaybeObject* maybe_properties = properties()->CopySize(out_of_object);
1552 if (!maybe_properties->To(&new_properties)) return maybe_properties;
1553 set_properties(new_properties);
1554 }
1555 set_map(map);
1556 return this;
1557}
1558
1559
danno@chromium.orgf005df62013-04-30 16:36:45 +00001560MaybeObject* JSObject::MigrateInstance() {
1561 // Converting any field to the most specific type will cause the
1562 // GeneralizeFieldRepresentation algorithm to create the most general existing
1563 // transition that matches the object. This achieves what is needed.
danno@chromium.org1fd77d52013-06-07 16:01:45 +00001564 return GeneralizeFieldRepresentation(0, Representation::None());
danno@chromium.orgf005df62013-04-30 16:36:45 +00001565}
1566
1567
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00001568MaybeObject* JSObject::TryMigrateInstance() {
1569 Map* new_map = map()->CurrentMapForDeprecated();
1570 if (new_map == NULL) return Smi::FromInt(0);
1571 return MigrateToMap(new_map);
1572}
1573
1574
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001575Handle<String> JSObject::ExpectedTransitionKey(Handle<Map> map) {
rossberg@chromium.org79e79022013-06-03 15:43:46 +00001576 DisallowHeapAllocation no_gc;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001577 if (!map->HasTransitionArray()) return Handle<String>::null();
1578 TransitionArray* transitions = map->transitions();
1579 if (!transitions->IsSimpleTransition()) return Handle<String>::null();
1580 int transition = TransitionArray::kSimpleTransitionIndex;
1581 PropertyDetails details = transitions->GetTargetDetails(transition);
1582 Name* name = transitions->GetKey(transition);
1583 if (details.type() != FIELD) return Handle<String>::null();
1584 if (details.attributes() != NONE) return Handle<String>::null();
1585 if (!name->IsString()) return Handle<String>::null();
1586 return Handle<String>(String::cast(name));
1587}
1588
1589
1590Handle<Map> JSObject::ExpectedTransitionTarget(Handle<Map> map) {
1591 ASSERT(!ExpectedTransitionKey(map).is_null());
1592 return Handle<Map>(map->transitions()->GetTarget(
1593 TransitionArray::kSimpleTransitionIndex));
1594}
1595
1596
1597Handle<Map> JSObject::FindTransitionToField(Handle<Map> map, Handle<Name> key) {
rossberg@chromium.org79e79022013-06-03 15:43:46 +00001598 DisallowHeapAllocation no_allocation;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001599 if (!map->HasTransitionArray()) return Handle<Map>::null();
1600 TransitionArray* transitions = map->transitions();
1601 int transition = transitions->Search(*key);
1602 if (transition == TransitionArray::kNotFound) return Handle<Map>::null();
1603 PropertyDetails target_details = transitions->GetTargetDetails(transition);
1604 if (target_details.type() != FIELD) return Handle<Map>::null();
1605 if (target_details.attributes() != NONE) return Handle<Map>::null();
1606 return Handle<Map>(transitions->GetTarget(transition));
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00001607}
1608
1609
1610int JSObject::LastAddedFieldIndex() {
1611 Map* map = this->map();
1612 int last_added = map->LastAdded();
1613 return map->instance_descriptors()->GetFieldIndex(last_added);
1614}
1615
1616
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001617ACCESSORS(Oddball, to_string, String, kToStringOffset)
1618ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1619
1620
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001621byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001622 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001623}
1624
1625
1626void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001627 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001628}
1629
1630
danno@chromium.org41728482013-06-12 22:31:22 +00001631Object* Cell::value() {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001632 return READ_FIELD(this, kValueOffset);
1633}
1634
1635
danno@chromium.org41728482013-06-12 22:31:22 +00001636void Cell::set_value(Object* val, WriteBarrierMode ignored) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001637 // The write barrier is not used for global property cells.
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00001638 ASSERT(!val->IsPropertyCell() && !val->IsCell());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001639 WRITE_FIELD(this, kValueOffset, val);
1640}
1641
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001642ACCESSORS(PropertyCell, dependent_code, DependentCode, kDependentCodeOffset)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001643
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00001644Object* PropertyCell::type_raw() {
danno@chromium.org41728482013-06-12 22:31:22 +00001645 return READ_FIELD(this, kTypeOffset);
1646}
1647
1648
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00001649void PropertyCell::set_type_raw(Object* val, WriteBarrierMode ignored) {
danno@chromium.org41728482013-06-12 22:31:22 +00001650 WRITE_FIELD(this, kTypeOffset, val);
1651}
1652
1653
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001654int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001655 InstanceType type = map()->instance_type();
1656 // Check for the most common kind of JavaScript object before
1657 // falling into the generic switch. This speeds up the internal
1658 // field operations considerably on average.
1659 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1660 switch (type) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001661 case JS_GENERATOR_OBJECT_TYPE:
1662 return JSGeneratorObject::kSize;
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00001663 case JS_MODULE_TYPE:
1664 return JSModule::kSize;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001665 case JS_GLOBAL_PROXY_TYPE:
1666 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001667 case JS_GLOBAL_OBJECT_TYPE:
1668 return JSGlobalObject::kSize;
1669 case JS_BUILTINS_OBJECT_TYPE:
1670 return JSBuiltinsObject::kSize;
1671 case JS_FUNCTION_TYPE:
1672 return JSFunction::kSize;
1673 case JS_VALUE_TYPE:
1674 return JSValue::kSize;
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00001675 case JS_DATE_TYPE:
1676 return JSDate::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001677 case JS_ARRAY_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001678 return JSArray::kSize;
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001679 case JS_ARRAY_BUFFER_TYPE:
1680 return JSArrayBuffer::kSize;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001681 case JS_TYPED_ARRAY_TYPE:
1682 return JSTypedArray::kSize;
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001683 case JS_DATA_VIEW_TYPE:
1684 return JSDataView::kSize;
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001685 case JS_SET_TYPE:
1686 return JSSet::kSize;
1687 case JS_MAP_TYPE:
1688 return JSMap::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001689 case JS_WEAK_MAP_TYPE:
1690 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001691 case JS_REGEXP_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001692 return JSRegExp::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001693 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001694 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001695 case JS_MESSAGE_OBJECT_TYPE:
1696 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001697 default:
1698 UNREACHABLE();
1699 return 0;
1700 }
1701}
1702
1703
1704int JSObject::GetInternalFieldCount() {
1705 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001706 // Make sure to adjust for the number of in-object properties. These
1707 // properties do contribute to the size, but are not internal fields.
1708 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1709 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001710}
1711
1712
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001713int JSObject::GetInternalFieldOffset(int index) {
1714 ASSERT(index < GetInternalFieldCount() && index >= 0);
1715 return GetHeaderSize() + (kPointerSize * index);
1716}
1717
1718
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001719Object* JSObject::GetInternalField(int index) {
1720 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001721 // Internal objects do follow immediately after the header, whereas in-object
1722 // properties are at the end of the object. Therefore there is no need
1723 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001724 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1725}
1726
1727
1728void JSObject::SetInternalField(int index, Object* value) {
1729 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001730 // Internal objects do follow immediately after the header, whereas in-object
1731 // properties are at the end of the object. Therefore there is no need
1732 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001733 int offset = GetHeaderSize() + (kPointerSize * index);
1734 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001735 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001736}
1737
1738
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001739void JSObject::SetInternalField(int index, Smi* value) {
1740 ASSERT(index < GetInternalFieldCount() && index >= 0);
1741 // Internal objects do follow immediately after the header, whereas in-object
1742 // properties are at the end of the object. Therefore there is no need
1743 // to adjust the index here.
1744 int offset = GetHeaderSize() + (kPointerSize * index);
1745 WRITE_FIELD(this, offset, value);
1746}
1747
1748
ulan@chromium.org57ff8812013-05-10 08:16:55 +00001749MaybeObject* JSObject::FastPropertyAt(Representation representation,
1750 int index) {
1751 Object* raw_value = RawFastPropertyAt(index);
1752 return raw_value->AllocateNewStorageFor(GetHeap(), representation);
1753}
1754
1755
ager@chromium.org7c537e22008-10-16 08:43:32 +00001756// Access fast-case object properties at index. The use of these routines
1757// is needed to correctly distinguish between properties stored in-object and
1758// properties stored in the properties array.
ulan@chromium.org57ff8812013-05-10 08:16:55 +00001759Object* JSObject::RawFastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001760 // Adjust for the number of properties stored in the object.
1761 index -= map()->inobject_properties();
1762 if (index < 0) {
1763 int offset = map()->instance_size() + (index * kPointerSize);
1764 return READ_FIELD(this, offset);
1765 } else {
1766 ASSERT(index < properties()->length());
1767 return properties()->get(index);
1768 }
1769}
1770
1771
ulan@chromium.org57ff8812013-05-10 08:16:55 +00001772void JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001773 // Adjust for the number of properties stored in the object.
1774 index -= map()->inobject_properties();
1775 if (index < 0) {
1776 int offset = map()->instance_size() + (index * kPointerSize);
1777 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001778 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001779 } else {
1780 ASSERT(index < properties()->length());
1781 properties()->set(index, value);
1782 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001783}
1784
1785
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001786int JSObject::GetInObjectPropertyOffset(int index) {
1787 // Adjust for the number of properties stored in the object.
1788 index -= map()->inobject_properties();
1789 ASSERT(index < 0);
1790 return map()->instance_size() + (index * kPointerSize);
1791}
1792
1793
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001794Object* JSObject::InObjectPropertyAt(int index) {
1795 // Adjust for the number of properties stored in the object.
1796 index -= map()->inobject_properties();
1797 ASSERT(index < 0);
1798 int offset = map()->instance_size() + (index * kPointerSize);
1799 return READ_FIELD(this, offset);
1800}
1801
1802
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001803Object* JSObject::InObjectPropertyAtPut(int index,
1804 Object* value,
1805 WriteBarrierMode mode) {
1806 // Adjust for the number of properties stored in the object.
1807 index -= map()->inobject_properties();
1808 ASSERT(index < 0);
1809 int offset = map()->instance_size() + (index * kPointerSize);
1810 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001811 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001812 return value;
1813}
1814
1815
1816
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001817void JSObject::InitializeBody(Map* map,
1818 Object* pre_allocated_value,
1819 Object* filler_value) {
1820 ASSERT(!filler_value->IsHeapObject() ||
1821 !GetHeap()->InNewSpace(filler_value));
1822 ASSERT(!pre_allocated_value->IsHeapObject() ||
1823 !GetHeap()->InNewSpace(pre_allocated_value));
1824 int size = map->instance_size();
1825 int offset = kHeaderSize;
1826 if (filler_value != pre_allocated_value) {
1827 int pre_allocated = map->pre_allocated_property_fields();
1828 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1829 for (int i = 0; i < pre_allocated; i++) {
1830 WRITE_FIELD(this, offset, pre_allocated_value);
1831 offset += kPointerSize;
1832 }
1833 }
1834 while (offset < size) {
1835 WRITE_FIELD(this, offset, filler_value);
1836 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001837 }
1838}
1839
1840
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001841bool JSObject::HasFastProperties() {
erik.corry@gmail.com88767242012-08-08 14:43:45 +00001842 ASSERT(properties()->IsDictionary() == map()->is_dictionary_map());
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001843 return !properties()->IsDictionary();
1844}
1845
1846
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001847bool JSObject::TooManyFastProperties(int properties,
1848 JSObject::StoreFromKeyed store_mode) {
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001849 // Allow extra fast properties if the object has more than
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001850 // kFastPropertiesSoftLimit in-object properties. When this is the case,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001851 // it is very unlikely that the object is being used as a dictionary
1852 // and there is a good chance that allowing more map transitions
1853 // will be worth it.
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001854 int inobject = map()->inobject_properties();
1855
1856 int limit;
ulan@chromium.orgf6a0c412012-06-15 12:31:06 +00001857 if (store_mode == CERTAINLY_NOT_STORE_FROM_KEYED) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001858 limit = Max(inobject, kMaxFastProperties);
1859 } else {
1860 limit = Max(inobject, kFastPropertiesSoftLimit);
1861 }
1862 return properties > limit;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001863}
1864
1865
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001866void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001867 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001868 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001869 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001870 }
1871}
1872
1873
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001874bool Object::ToArrayIndex(uint32_t* index) {
1875 if (IsSmi()) {
1876 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001877 if (value < 0) return false;
1878 *index = value;
1879 return true;
1880 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001881 if (IsHeapNumber()) {
1882 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001883 uint32_t uint_value = static_cast<uint32_t>(value);
1884 if (value == static_cast<double>(uint_value)) {
1885 *index = uint_value;
1886 return true;
1887 }
1888 }
1889 return false;
1890}
1891
1892
1893bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1894 if (!this->IsJSValue()) return false;
1895
1896 JSValue* js_value = JSValue::cast(this);
1897 if (!js_value->value()->IsString()) return false;
1898
1899 String* str = String::cast(js_value->value());
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00001900 if (index >= static_cast<uint32_t>(str->length())) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001901
1902 return true;
1903}
1904
1905
mstarzinger@chromium.orgde886792012-09-11 13:22:37 +00001906
1907void Object::VerifyApiCallResultType() {
1908#if ENABLE_EXTRA_CHECKS
1909 if (!(IsSmi() ||
1910 IsString() ||
1911 IsSpecObject() ||
1912 IsHeapNumber() ||
1913 IsUndefined() ||
1914 IsTrue() ||
1915 IsFalse() ||
1916 IsNull())) {
1917 FATAL("API call returned invalid object");
1918 }
1919#endif // ENABLE_EXTRA_CHECKS
1920}
1921
1922
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001923FixedArrayBase* FixedArrayBase::cast(Object* object) {
1924 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1925 return reinterpret_cast<FixedArrayBase*>(object);
1926}
1927
1928
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001929Object* FixedArray::get(int index) {
1930 ASSERT(index >= 0 && index < this->length());
1931 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1932}
1933
1934
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001935bool FixedArray::is_the_hole(int index) {
1936 return get(index) == GetHeap()->the_hole_value();
1937}
1938
1939
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001940void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001941 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001942 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001943 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1944 int offset = kHeaderSize + index * kPointerSize;
1945 WRITE_FIELD(this, offset, value);
1946}
1947
1948
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001949void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001950 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001951 ASSERT(index >= 0 && index < this->length());
1952 int offset = kHeaderSize + index * kPointerSize;
1953 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001954 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001955}
1956
1957
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001958inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1959 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1960}
1961
1962
1963inline double FixedDoubleArray::hole_nan_as_double() {
1964 return BitCast<double, uint64_t>(kHoleNanInt64);
1965}
1966
1967
1968inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1969 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1970 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1971 return OS::nan_value();
1972}
1973
1974
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001975double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001976 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1977 map() != HEAP->fixed_array_map());
1978 ASSERT(index >= 0 && index < this->length());
1979 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1980 ASSERT(!is_the_hole_nan(result));
1981 return result;
1982}
1983
danno@chromium.org88aa0582012-03-23 15:11:57 +00001984int64_t FixedDoubleArray::get_representation(int index) {
1985 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1986 map() != HEAP->fixed_array_map());
1987 ASSERT(index >= 0 && index < this->length());
1988 return READ_INT64_FIELD(this, kHeaderSize + index * kDoubleSize);
1989}
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001990
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001991MaybeObject* FixedDoubleArray::get(int index) {
1992 if (is_the_hole(index)) {
1993 return GetHeap()->the_hole_value();
1994 } else {
1995 return GetHeap()->NumberFromDouble(get_scalar(index));
1996 }
1997}
1998
1999
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002000void FixedDoubleArray::set(int index, double value) {
2001 ASSERT(map() != HEAP->fixed_cow_array_map() &&
2002 map() != HEAP->fixed_array_map());
2003 int offset = kHeaderSize + index * kDoubleSize;
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00002004 if (std::isnan(value)) value = canonical_not_the_hole_nan_as_double();
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002005 WRITE_DOUBLE_FIELD(this, offset, value);
2006}
2007
2008
2009void FixedDoubleArray::set_the_hole(int index) {
2010 ASSERT(map() != HEAP->fixed_cow_array_map() &&
2011 map() != HEAP->fixed_array_map());
2012 int offset = kHeaderSize + index * kDoubleSize;
2013 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
2014}
2015
2016
2017bool FixedDoubleArray::is_the_hole(int index) {
2018 int offset = kHeaderSize + index * kDoubleSize;
2019 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
2020}
2021
2022
rossberg@chromium.org79e79022013-06-03 15:43:46 +00002023WriteBarrierMode HeapObject::GetWriteBarrierMode(
2024 const DisallowHeapAllocation& promise) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002025 Heap* heap = GetHeap();
2026 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
2027 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002028 return UPDATE_WRITE_BARRIER;
2029}
2030
2031
2032void FixedArray::set(int index,
2033 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002034 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002035 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002036 ASSERT(index >= 0 && index < this->length());
2037 int offset = kHeaderSize + index * kPointerSize;
2038 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002039 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002040}
2041
2042
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002043void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
2044 int index,
2045 Object* value) {
danno@chromium.org72204d52012-10-31 10:02:10 +00002046 ASSERT(array->map() != HEAP->fixed_cow_array_map());
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002047 ASSERT(index >= 0 && index < array->length());
2048 int offset = kHeaderSize + index * kPointerSize;
2049 WRITE_FIELD(array, offset, value);
2050 Heap* heap = array->GetHeap();
2051 if (heap->InNewSpace(value)) {
2052 heap->RecordWrite(array->address(), offset);
2053 }
2054}
2055
2056
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002057void FixedArray::NoWriteBarrierSet(FixedArray* array,
2058 int index,
2059 Object* value) {
danno@chromium.org72204d52012-10-31 10:02:10 +00002060 ASSERT(array->map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002061 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002062 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002063 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
2064}
2065
2066
2067void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002068 ASSERT(map() != HEAP->fixed_cow_array_map());
2069 set_undefined(GetHeap(), index);
2070}
2071
2072
2073void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002074 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002075 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002076 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002077 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002078}
2079
2080
ager@chromium.org236ad962008-09-25 09:45:57 +00002081void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002082 set_null(GetHeap(), index);
2083}
2084
2085
2086void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00002087 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002088 ASSERT(!heap->InNewSpace(heap->null_value()));
2089 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002090}
2091
2092
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002093void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002094 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002095 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002096 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
2097 WRITE_FIELD(this,
2098 kHeaderSize + index * kPointerSize,
2099 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002100}
2101
2102
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002103double* FixedDoubleArray::data_start() {
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00002104 return reinterpret_cast<double*>(FIELD_ADDR(this, kHeaderSize));
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002105}
2106
2107
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002108Object** FixedArray::data_start() {
2109 return HeapObject::RawField(this, kHeaderSize);
2110}
2111
2112
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00002113bool DescriptorArray::IsEmpty() {
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00002114 ASSERT(length() >= kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002115 this == HEAP->empty_descriptor_array());
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00002116 return length() < kFirstIndex;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002117}
2118
2119
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002120void DescriptorArray::SetNumberOfDescriptors(int number_of_descriptors) {
2121 WRITE_FIELD(
2122 this, kDescriptorLengthOffset, Smi::FromInt(number_of_descriptors));
2123}
2124
2125
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002126// Perform a binary search in a fixed array. Low and high are entry indices. If
2127// there are three entries in this array it should be called with low=0 and
2128// high=2.
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002129template<SearchMode search_mode, typename T>
ulan@chromium.org750145a2013-03-07 15:14:13 +00002130int BinarySearch(T* array, Name* name, int low, int high, int valid_entries) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002131 uint32_t hash = name->Hash();
2132 int limit = high;
2133
2134 ASSERT(low <= high);
2135
2136 while (low != high) {
2137 int mid = (low + high) / 2;
ulan@chromium.org750145a2013-03-07 15:14:13 +00002138 Name* mid_name = array->GetSortedKey(mid);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002139 uint32_t mid_hash = mid_name->Hash();
2140
2141 if (mid_hash >= hash) {
2142 high = mid;
2143 } else {
2144 low = mid + 1;
2145 }
2146 }
2147
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002148 for (; low <= limit; ++low) {
2149 int sort_index = array->GetSortedKeyIndex(low);
ulan@chromium.org750145a2013-03-07 15:14:13 +00002150 Name* entry = array->GetKey(sort_index);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002151 if (entry->Hash() != hash) break;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002152 if (entry->Equals(name)) {
2153 if (search_mode == ALL_ENTRIES || sort_index < valid_entries) {
2154 return sort_index;
2155 }
2156 return T::kNotFound;
2157 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002158 }
2159
2160 return T::kNotFound;
2161}
2162
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002163
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002164// Perform a linear search in this fixed array. len is the number of entry
2165// indices that are valid.
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002166template<SearchMode search_mode, typename T>
ulan@chromium.org750145a2013-03-07 15:14:13 +00002167int LinearSearch(T* array, Name* name, int len, int valid_entries) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002168 uint32_t hash = name->Hash();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002169 if (search_mode == ALL_ENTRIES) {
2170 for (int number = 0; number < len; number++) {
2171 int sorted_index = array->GetSortedKeyIndex(number);
ulan@chromium.org750145a2013-03-07 15:14:13 +00002172 Name* entry = array->GetKey(sorted_index);
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002173 uint32_t current_hash = entry->Hash();
2174 if (current_hash > hash) break;
2175 if (current_hash == hash && entry->Equals(name)) return sorted_index;
2176 }
2177 } else {
2178 ASSERT(len >= valid_entries);
2179 for (int number = 0; number < valid_entries; number++) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002180 Name* entry = array->GetKey(number);
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002181 uint32_t current_hash = entry->Hash();
2182 if (current_hash == hash && entry->Equals(name)) return number;
2183 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002184 }
2185 return T::kNotFound;
2186}
2187
2188
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002189template<SearchMode search_mode, typename T>
ulan@chromium.org750145a2013-03-07 15:14:13 +00002190int Search(T* array, Name* name, int valid_entries) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002191 if (search_mode == VALID_ENTRIES) {
2192 SLOW_ASSERT(array->IsSortedNoDuplicates(valid_entries));
2193 } else {
2194 SLOW_ASSERT(array->IsSortedNoDuplicates());
2195 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002196
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002197 int nof = array->number_of_entries();
2198 if (nof == 0) return T::kNotFound;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002199
2200 // Fast case: do linear search for small arrays.
2201 const int kMaxElementsForLinearSearch = 8;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002202 if ((search_mode == ALL_ENTRIES &&
2203 nof <= kMaxElementsForLinearSearch) ||
2204 (search_mode == VALID_ENTRIES &&
2205 valid_entries <= (kMaxElementsForLinearSearch * 3))) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002206 return LinearSearch<search_mode>(array, name, nof, valid_entries);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002207 }
2208
2209 // Slow case: perform binary search.
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002210 return BinarySearch<search_mode>(array, name, 0, nof - 1, valid_entries);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002211}
2212
2213
ulan@chromium.org750145a2013-03-07 15:14:13 +00002214int DescriptorArray::Search(Name* name, int valid_descriptors) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002215 return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002216}
2217
2218
ulan@chromium.org750145a2013-03-07 15:14:13 +00002219int DescriptorArray::SearchWithCache(Name* name, Map* map) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002220 int number_of_own_descriptors = map->NumberOfOwnDescriptors();
2221 if (number_of_own_descriptors == 0) return kNotFound;
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002222
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002223 DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002224 int number = cache->Lookup(map, name);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002225
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002226 if (number == DescriptorLookupCache::kAbsent) {
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002227 number = Search(name, number_of_own_descriptors);
2228 cache->Update(map, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002229 }
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002230
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002231 return number;
2232}
2233
2234
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002235void Map::LookupDescriptor(JSObject* holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +00002236 Name* name,
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002237 LookupResult* result) {
2238 DescriptorArray* descriptors = this->instance_descriptors();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002239 int number = descriptors->SearchWithCache(name, this);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002240 if (number == DescriptorArray::kNotFound) return result->NotFound();
2241 result->DescriptorResult(holder, descriptors->GetDetails(number), number);
2242}
2243
2244
2245void Map::LookupTransition(JSObject* holder,
ulan@chromium.org750145a2013-03-07 15:14:13 +00002246 Name* name,
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002247 LookupResult* result) {
2248 if (HasTransitionArray()) {
2249 TransitionArray* transition_array = transitions();
2250 int number = transition_array->Search(name);
2251 if (number != TransitionArray::kNotFound) {
2252 return result->TransitionResult(holder, number);
2253 }
2254 }
2255 result->NotFound();
2256}
2257
2258
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002259Object** DescriptorArray::GetKeySlot(int descriptor_number) {
2260 ASSERT(descriptor_number < number_of_descriptors());
2261 return HeapObject::RawField(
2262 reinterpret_cast<HeapObject*>(this),
2263 OffsetOfElementAt(ToKeyIndex(descriptor_number)));
2264}
2265
2266
mstarzinger@chromium.orge3b8d0f2013-02-01 09:06:41 +00002267Object** DescriptorArray::GetDescriptorStartSlot(int descriptor_number) {
2268 return GetKeySlot(descriptor_number);
2269}
2270
2271
2272Object** DescriptorArray::GetDescriptorEndSlot(int descriptor_number) {
2273 return GetValueSlot(descriptor_number - 1) + 1;
2274}
2275
2276
ulan@chromium.org750145a2013-03-07 15:14:13 +00002277Name* DescriptorArray::GetKey(int descriptor_number) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002278 ASSERT(descriptor_number < number_of_descriptors());
ulan@chromium.org750145a2013-03-07 15:14:13 +00002279 return Name::cast(get(ToKeyIndex(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002280}
2281
2282
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002283int DescriptorArray::GetSortedKeyIndex(int descriptor_number) {
2284 return GetDetails(descriptor_number).pointer();
2285}
2286
2287
ulan@chromium.org750145a2013-03-07 15:14:13 +00002288Name* DescriptorArray::GetSortedKey(int descriptor_number) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002289 return GetKey(GetSortedKeyIndex(descriptor_number));
2290}
2291
2292
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002293void DescriptorArray::SetSortedKey(int descriptor_index, int pointer) {
2294 PropertyDetails details = GetDetails(descriptor_index);
2295 set(ToDetailsIndex(descriptor_index), details.set_pointer(pointer).AsSmi());
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002296}
2297
2298
danno@chromium.orgf005df62013-04-30 16:36:45 +00002299void DescriptorArray::SetRepresentation(int descriptor_index,
2300 Representation representation) {
2301 ASSERT(!representation.IsNone());
2302 PropertyDetails details = GetDetails(descriptor_index);
2303 set(ToDetailsIndex(descriptor_index),
2304 details.CopyWithRepresentation(representation).AsSmi());
2305}
2306
2307
2308void DescriptorArray::InitializeRepresentations(Representation representation) {
2309 int length = number_of_descriptors();
2310 for (int i = 0; i < length; i++) {
2311 SetRepresentation(i, representation);
2312 }
2313}
2314
2315
verwaest@chromium.org37141392012-05-31 13:27:02 +00002316Object** DescriptorArray::GetValueSlot(int descriptor_number) {
2317 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002318 return HeapObject::RawField(
2319 reinterpret_cast<HeapObject*>(this),
2320 OffsetOfElementAt(ToValueIndex(descriptor_number)));
verwaest@chromium.org37141392012-05-31 13:27:02 +00002321}
2322
2323
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002324Object* DescriptorArray::GetValue(int descriptor_number) {
2325 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002326 return get(ToValueIndex(descriptor_number));
2327}
2328
2329
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002330PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002331 ASSERT(descriptor_number < number_of_descriptors());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002332 Object* details = get(ToDetailsIndex(descriptor_number));
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002333 return PropertyDetails(Smi::cast(details));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002334}
2335
2336
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002337PropertyType DescriptorArray::GetType(int descriptor_number) {
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002338 return GetDetails(descriptor_number).type();
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002339}
2340
2341
2342int DescriptorArray::GetFieldIndex(int descriptor_number) {
rossberg@chromium.org79e79022013-06-03 15:43:46 +00002343 return GetDetails(descriptor_number).field_index();
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002344}
2345
2346
2347JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
2348 return JSFunction::cast(GetValue(descriptor_number));
2349}
2350
2351
2352Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
2353 ASSERT(GetType(descriptor_number) == CALLBACKS);
2354 return GetValue(descriptor_number);
2355}
2356
2357
2358AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
2359 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002360 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002361 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002362}
2363
2364
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002365void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2366 desc->Init(GetKey(descriptor_number),
2367 GetValue(descriptor_number),
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00002368 GetDetails(descriptor_number));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002369}
2370
2371
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002372void DescriptorArray::Set(int descriptor_number,
2373 Descriptor* desc,
2374 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002375 // Range check.
2376 ASSERT(descriptor_number < number_of_descriptors());
2377
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002378 NoIncrementalWriteBarrierSet(this,
2379 ToKeyIndex(descriptor_number),
2380 desc->GetKey());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002381 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002382 ToValueIndex(descriptor_number),
2383 desc->GetValue());
rossberg@chromium.org400388e2012-06-06 09:29:22 +00002384 NoIncrementalWriteBarrierSet(this,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002385 ToDetailsIndex(descriptor_number),
2386 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002387}
2388
2389
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002390void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
2391 // Range check.
2392 ASSERT(descriptor_number < number_of_descriptors());
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002393
2394 set(ToKeyIndex(descriptor_number), desc->GetKey());
2395 set(ToValueIndex(descriptor_number), desc->GetValue());
2396 set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi());
2397}
2398
2399
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002400void DescriptorArray::Append(Descriptor* desc,
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002401 const WhitenessWitness& witness) {
2402 int descriptor_number = number_of_descriptors();
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002403 SetNumberOfDescriptors(descriptor_number + 1);
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002404 Set(descriptor_number, desc, witness);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002405
2406 uint32_t hash = desc->GetKey()->Hash();
2407
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002408 int insertion;
2409
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002410 for (insertion = descriptor_number; insertion > 0; --insertion) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002411 Name* key = GetSortedKey(insertion - 1);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002412 if (key->Hash() <= hash) break;
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002413 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002414 }
2415
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00002416 SetSortedKey(insertion, descriptor_number);
ulan@chromium.org56c14af2012-09-20 12:51:09 +00002417}
2418
2419
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002420void DescriptorArray::Append(Descriptor* desc) {
2421 int descriptor_number = number_of_descriptors();
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002422 SetNumberOfDescriptors(descriptor_number + 1);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002423 Set(descriptor_number, desc);
2424
2425 uint32_t hash = desc->GetKey()->Hash();
2426
2427 int insertion;
2428
2429 for (insertion = descriptor_number; insertion > 0; --insertion) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002430 Name* key = GetSortedKey(insertion - 1);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00002431 if (key->Hash() <= hash) break;
2432 SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
2433 }
2434
2435 SetSortedKey(insertion, descriptor_number);
2436}
2437
2438
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00002439void DescriptorArray::SwapSortedKeys(int first, int second) {
2440 int first_key = GetSortedKeyIndex(first);
2441 SetSortedKey(first, GetSortedKeyIndex(second));
2442 SetSortedKey(second, first_key);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002443}
2444
2445
ulan@chromium.org56c14af2012-09-20 12:51:09 +00002446DescriptorArray::WhitenessWitness::WhitenessWitness(FixedArray* array)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002447 : marking_(array->GetHeap()->incremental_marking()) {
2448 marking_->EnterNoMarkingScope();
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00002449 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002450}
2451
2452
ulan@chromium.org56c14af2012-09-20 12:51:09 +00002453DescriptorArray::WhitenessWitness::~WhitenessWitness() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002454 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002455}
2456
2457
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002458template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002459int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2460 const int kMinCapacity = 32;
2461 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2462 if (capacity < kMinCapacity) {
2463 capacity = kMinCapacity; // Guarantee min capacity.
2464 }
2465 return capacity;
2466}
2467
2468
2469template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002470int HashTable<Shape, Key>::FindEntry(Key key) {
2471 return FindEntry(GetIsolate(), key);
2472}
2473
2474
2475// Find entry for key otherwise return kNotFound.
2476template<typename Shape, typename Key>
2477int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2478 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002479 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002480 uint32_t count = 1;
2481 // EnsureCapacity will guarantee the hash table is never full.
2482 while (true) {
2483 Object* element = KeyAt(entry);
danno@chromium.org72204d52012-10-31 10:02:10 +00002484 // Empty entry. Uses raw unchecked accessors because it is called by the
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002485 // string table during bootstrapping.
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002486 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2487 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002488 Shape::IsMatch(key, element)) return entry;
2489 entry = NextProbe(entry, count++, capacity);
2490 }
2491 return kNotFound;
2492}
2493
2494
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002495bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002496 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002497 if (!max_index_object->IsSmi()) return false;
2498 return 0 !=
2499 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2500}
2501
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002502uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002503 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002504 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002505 if (!max_index_object->IsSmi()) return 0;
2506 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2507 return value >> kRequiresSlowElementsTagSize;
2508}
2509
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002510void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002511 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002512}
2513
2514
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002515// ------------------------------------
2516// Cast operations
2517
2518
2519CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002520CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002521CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002522CAST_ACCESSOR(DeoptimizationInputData)
2523CAST_ACCESSOR(DeoptimizationOutputData)
ulan@chromium.org2e04b582013-02-21 14:06:02 +00002524CAST_ACCESSOR(DependentCode)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002525CAST_ACCESSOR(TypeFeedbackCells)
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002526CAST_ACCESSOR(StringTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002527CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002528CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002529CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002530CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002531CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002532CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002533CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002534CAST_ACCESSOR(String)
2535CAST_ACCESSOR(SeqString)
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002536CAST_ACCESSOR(SeqOneByteString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002537CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002538CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002539CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002540CAST_ACCESSOR(ExternalString)
2541CAST_ACCESSOR(ExternalAsciiString)
2542CAST_ACCESSOR(ExternalTwoByteString)
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002543CAST_ACCESSOR(Symbol)
ulan@chromium.org750145a2013-03-07 15:14:13 +00002544CAST_ACCESSOR(Name)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002545CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002546CAST_ACCESSOR(JSObject)
2547CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002548CAST_ACCESSOR(HeapObject)
2549CAST_ACCESSOR(HeapNumber)
2550CAST_ACCESSOR(Oddball)
danno@chromium.org41728482013-06-12 22:31:22 +00002551CAST_ACCESSOR(Cell)
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00002552CAST_ACCESSOR(PropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002553CAST_ACCESSOR(SharedFunctionInfo)
2554CAST_ACCESSOR(Map)
2555CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002556CAST_ACCESSOR(GlobalObject)
2557CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002558CAST_ACCESSOR(JSGlobalObject)
2559CAST_ACCESSOR(JSBuiltinsObject)
2560CAST_ACCESSOR(Code)
2561CAST_ACCESSOR(JSArray)
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00002562CAST_ACCESSOR(JSArrayBuffer)
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002563CAST_ACCESSOR(JSArrayBufferView)
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002564CAST_ACCESSOR(JSTypedArray)
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00002565CAST_ACCESSOR(JSDataView)
ager@chromium.org236ad962008-09-25 09:45:57 +00002566CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002567CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002568CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002569CAST_ACCESSOR(JSSet)
2570CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002571CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002572CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002573CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002574CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002575CAST_ACCESSOR(ExternalArray)
2576CAST_ACCESSOR(ExternalByteArray)
2577CAST_ACCESSOR(ExternalUnsignedByteArray)
2578CAST_ACCESSOR(ExternalShortArray)
2579CAST_ACCESSOR(ExternalUnsignedShortArray)
2580CAST_ACCESSOR(ExternalIntArray)
2581CAST_ACCESSOR(ExternalUnsignedIntArray)
2582CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002583CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002584CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002585CAST_ACCESSOR(Struct)
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002586CAST_ACCESSOR(AccessorInfo)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002587
2588
2589#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2590 STRUCT_LIST(MAKE_STRUCT_CAST)
2591#undef MAKE_STRUCT_CAST
2592
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002593
2594template <typename Shape, typename Key>
2595HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002596 ASSERT(obj->IsHashTable());
2597 return reinterpret_cast<HashTable*>(obj);
2598}
2599
2600
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002601SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002602SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002603
ager@chromium.orgac091b72010-05-05 07:34:42 +00002604SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002605
2606
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002607uint32_t Name::hash_field() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002608 return READ_UINT32_FIELD(this, kHashFieldOffset);
2609}
2610
2611
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002612void Name::set_hash_field(uint32_t value) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002613 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002614#if V8_HOST_ARCH_64_BIT
2615 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2616#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002617}
2618
2619
ulan@chromium.org750145a2013-03-07 15:14:13 +00002620bool Name::Equals(Name* other) {
2621 if (other == this) return true;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002622 if ((this->IsInternalizedString() && other->IsInternalizedString()) ||
2623 this->IsSymbol() || other->IsSymbol()) {
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00002624 return false;
2625 }
ulan@chromium.org750145a2013-03-07 15:14:13 +00002626 return String::cast(this)->SlowEquals(String::cast(other));
2627}
2628
2629
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00002630ACCESSORS(Symbol, name, Object, kNameOffset)
2631
2632
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002633bool String::Equals(String* other) {
2634 if (other == this) return true;
ulan@chromium.org750145a2013-03-07 15:14:13 +00002635 if (this->IsInternalizedString() && other->IsInternalizedString()) {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002636 return false;
2637 }
2638 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002639}
2640
2641
lrn@chromium.org303ada72010-10-27 09:33:13 +00002642MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002643 if (!StringShape(this).IsCons()) return this;
2644 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002645 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002646 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002647}
2648
2649
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002650String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002651 MaybeObject* flat = TryFlatten(pretenure);
2652 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002653 if (!flat->ToObject(&successfully_flattened)) return this;
2654 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002655}
2656
2657
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002658uint16_t String::Get(int index) {
2659 ASSERT(index >= 0 && index < length());
2660 switch (StringShape(this).full_representation_tag()) {
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002661 case kSeqStringTag | kOneByteStringTag:
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002662 return SeqOneByteString::cast(this)->SeqOneByteStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002663 case kSeqStringTag | kTwoByteStringTag:
2664 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002665 case kConsStringTag | kOneByteStringTag:
ager@chromium.org870a0b62008-11-04 11:43:05 +00002666 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002667 return ConsString::cast(this)->ConsStringGet(index);
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002668 case kExternalStringTag | kOneByteStringTag:
ager@chromium.org870a0b62008-11-04 11:43:05 +00002669 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2670 case kExternalStringTag | kTwoByteStringTag:
2671 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00002672 case kSlicedStringTag | kOneByteStringTag:
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002673 case kSlicedStringTag | kTwoByteStringTag:
2674 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002675 default:
2676 break;
2677 }
2678
2679 UNREACHABLE();
2680 return 0;
2681}
2682
2683
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002684void String::Set(int index, uint16_t value) {
2685 ASSERT(index >= 0 && index < length());
2686 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002687
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00002688 return this->IsOneByteRepresentation()
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002689 ? SeqOneByteString::cast(this)->SeqOneByteStringSet(index, value)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002690 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002691}
2692
2693
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002694bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002695 if (!StringShape(this).IsCons()) return true;
2696 return ConsString::cast(this)->second()->length() == 0;
2697}
2698
2699
2700String* String::GetUnderlying() {
2701 // Giving direct access to underlying string only makes sense if the
2702 // wrapping string is already flattened.
2703 ASSERT(this->IsFlat());
2704 ASSERT(StringShape(this).IsIndirect());
2705 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2706 const int kUnderlyingOffset = SlicedString::kParentOffset;
2707 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002708}
2709
2710
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002711template<class Visitor, class ConsOp>
2712void String::Visit(
2713 String* string,
2714 unsigned offset,
2715 Visitor& visitor,
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002716 ConsOp& cons_op,
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002717 int32_t type,
2718 unsigned length) {
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002719 ASSERT(length == static_cast<unsigned>(string->length()));
2720 ASSERT(offset <= length);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002721 unsigned slice_offset = offset;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002722 while (true) {
2723 ASSERT(type == string->map()->instance_type());
2724
2725 switch (type & (kStringRepresentationMask | kStringEncodingMask)) {
2726 case kSeqStringTag | kOneByteStringTag:
2727 visitor.VisitOneByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002728 SeqOneByteString::cast(string)->GetChars() + slice_offset,
2729 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002730 return;
2731
2732 case kSeqStringTag | kTwoByteStringTag:
2733 visitor.VisitTwoByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002734 SeqTwoByteString::cast(string)->GetChars() + slice_offset,
2735 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002736 return;
2737
2738 case kExternalStringTag | kOneByteStringTag:
2739 visitor.VisitOneByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002740 ExternalAsciiString::cast(string)->GetChars() + slice_offset,
2741 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002742 return;
2743
2744 case kExternalStringTag | kTwoByteStringTag:
2745 visitor.VisitTwoByteString(
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002746 ExternalTwoByteString::cast(string)->GetChars() + slice_offset,
2747 length - offset);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002748 return;
2749
2750 case kSlicedStringTag | kOneByteStringTag:
2751 case kSlicedStringTag | kTwoByteStringTag: {
2752 SlicedString* slicedString = SlicedString::cast(string);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002753 slice_offset += slicedString->offset();
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002754 string = slicedString->parent();
2755 type = string->map()->instance_type();
2756 continue;
2757 }
2758
2759 case kConsStringTag | kOneByteStringTag:
2760 case kConsStringTag | kTwoByteStringTag:
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002761 string = cons_op.Operate(string, &offset, &type, &length);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002762 if (string == NULL) return;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002763 slice_offset = offset;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002764 ASSERT(length == static_cast<unsigned>(string->length()));
2765 continue;
2766
2767 default:
2768 UNREACHABLE();
2769 return;
2770 }
2771 }
2772}
2773
2774
ulan@chromium.org750145a2013-03-07 15:14:13 +00002775// TODO(dcarney): Remove this class after conversion to VisitFlat.
2776class ConsStringCaptureOp {
2777 public:
2778 inline ConsStringCaptureOp() : cons_string_(NULL) {}
2779 inline String* Operate(String* string, unsigned*, int32_t*, unsigned*) {
2780 cons_string_ = ConsString::cast(string);
2781 return NULL;
2782 }
2783 ConsString* cons_string_;
2784};
2785
2786
2787template<class Visitor>
2788ConsString* String::VisitFlat(Visitor* visitor,
2789 String* string,
2790 int offset,
2791 int length,
2792 int32_t type) {
2793 ASSERT(length >= 0 && length == string->length());
2794 ASSERT(offset >= 0 && offset <= length);
2795 ConsStringCaptureOp op;
2796 Visit(string, offset, *visitor, op, type, static_cast<unsigned>(length));
2797 return op.cons_string_;
2798}
2799
2800
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002801uint16_t SeqOneByteString::SeqOneByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002802 ASSERT(index >= 0 && index < length());
2803 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2804}
2805
2806
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002807void SeqOneByteString::SeqOneByteStringSet(int index, uint16_t value) {
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002808 ASSERT(index >= 0 && index < length() && value <= kMaxOneByteCharCode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002809 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2810 static_cast<byte>(value));
2811}
2812
2813
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002814Address SeqOneByteString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002815 return FIELD_ADDR(this, kHeaderSize);
2816}
2817
2818
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002819uint8_t* SeqOneByteString::GetChars() {
2820 return reinterpret_cast<uint8_t*>(GetCharsAddress());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002821}
2822
2823
ager@chromium.org7c537e22008-10-16 08:43:32 +00002824Address SeqTwoByteString::GetCharsAddress() {
2825 return FIELD_ADDR(this, kHeaderSize);
2826}
2827
2828
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002829uc16* SeqTwoByteString::GetChars() {
2830 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2831}
2832
2833
ager@chromium.org7c537e22008-10-16 08:43:32 +00002834uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002835 ASSERT(index >= 0 && index < length());
2836 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2837}
2838
2839
ager@chromium.org7c537e22008-10-16 08:43:32 +00002840void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002841 ASSERT(index >= 0 && index < length());
2842 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2843}
2844
2845
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002846int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002847 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002848}
2849
2850
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002851int SeqOneByteString::SeqOneByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002852 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002853}
2854
2855
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002856String* SlicedString::parent() {
2857 return String::cast(READ_FIELD(this, kParentOffset));
2858}
2859
2860
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002861void SlicedString::set_parent(String* parent, WriteBarrierMode mode) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002862 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002863 WRITE_FIELD(this, kParentOffset, parent);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002864 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kParentOffset, parent, mode);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002865}
2866
2867
2868SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2869
2870
ager@chromium.org870a0b62008-11-04 11:43:05 +00002871String* ConsString::first() {
2872 return String::cast(READ_FIELD(this, kFirstOffset));
2873}
2874
2875
2876Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002877 return READ_FIELD(this, kFirstOffset);
2878}
2879
2880
ager@chromium.org870a0b62008-11-04 11:43:05 +00002881void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002882 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002883 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002884}
2885
2886
ager@chromium.org870a0b62008-11-04 11:43:05 +00002887String* ConsString::second() {
2888 return String::cast(READ_FIELD(this, kSecondOffset));
2889}
2890
2891
2892Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002893 return READ_FIELD(this, kSecondOffset);
2894}
2895
2896
ager@chromium.org870a0b62008-11-04 11:43:05 +00002897void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002898 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002899 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002900}
2901
2902
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002903bool ExternalString::is_short() {
2904 InstanceType type = map()->instance_type();
2905 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002906}
2907
2908
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002909const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002910 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2911}
2912
2913
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002914void ExternalAsciiString::update_data_cache() {
2915 if (is_short()) return;
2916 const char** data_field =
2917 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2918 *data_field = resource()->data();
2919}
2920
2921
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002922void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002923 const ExternalAsciiString::Resource* resource) {
2924 *reinterpret_cast<const Resource**>(
2925 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002926 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002927}
2928
2929
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00002930const uint8_t* ExternalAsciiString::GetChars() {
2931 return reinterpret_cast<const uint8_t*>(resource()->data());
erikcorry0ad885c2011-11-21 13:51:57 +00002932}
2933
2934
2935uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2936 ASSERT(index >= 0 && index < length());
2937 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002938}
2939
2940
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002941const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002942 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2943}
2944
2945
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002946void ExternalTwoByteString::update_data_cache() {
2947 if (is_short()) return;
2948 const uint16_t** data_field =
2949 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2950 *data_field = resource()->data();
2951}
2952
2953
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002954void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002955 const ExternalTwoByteString::Resource* resource) {
2956 *reinterpret_cast<const Resource**>(
2957 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002958 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002959}
2960
2961
2962const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002963 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002964}
2965
2966
2967uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2968 ASSERT(index >= 0 && index < length());
2969 return GetChars()[index];
2970}
2971
2972
2973const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2974 unsigned start) {
2975 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002976}
2977
2978
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002979String* ConsStringNullOp::Operate(String*, unsigned*, int32_t*, unsigned*) {
2980 return NULL;
2981}
2982
2983
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002984unsigned ConsStringIteratorOp::OffsetForDepth(unsigned depth) {
2985 return depth & kDepthMask;
2986}
2987
2988
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002989void ConsStringIteratorOp::PushLeft(ConsString* string) {
2990 frames_[depth_++ & kDepthMask] = string;
2991}
2992
2993
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002994void ConsStringIteratorOp::PushRight(ConsString* string) {
2995 // Inplace update.
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002996 frames_[(depth_-1) & kDepthMask] = string;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00002997}
2998
2999
3000void ConsStringIteratorOp::AdjustMaximumDepth() {
3001 if (depth_ > maximum_depth_) maximum_depth_ = depth_;
3002}
3003
3004
3005void ConsStringIteratorOp::Pop() {
3006 ASSERT(depth_ > 0);
3007 ASSERT(depth_ <= maximum_depth_);
3008 depth_--;
3009}
3010
3011
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00003012bool ConsStringIteratorOp::HasMore() {
3013 return depth_ != 0;
3014}
3015
3016
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003017void ConsStringIteratorOp::Reset() {
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00003018 depth_ = 0;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00003019}
3020
3021
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003022String* ConsStringIteratorOp::ContinueOperation(int32_t* type_out,
3023 unsigned* length_out) {
3024 bool blew_stack = false;
3025 String* string = NextLeaf(&blew_stack, type_out, length_out);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00003026 // String found.
3027 if (string != NULL) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003028 // Verify output.
3029 ASSERT(*length_out == static_cast<unsigned>(string->length()));
3030 ASSERT(*type_out == string->map()->instance_type());
3031 return string;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00003032 }
3033 // Traversal complete.
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003034 if (!blew_stack) return NULL;
3035 // Restart search from root.
3036 unsigned offset_out;
3037 string = Search(&offset_out, type_out, length_out);
3038 // Verify output.
3039 ASSERT(string == NULL || offset_out == 0);
3040 ASSERT(string == NULL ||
3041 *length_out == static_cast<unsigned>(string->length()));
3042 ASSERT(string == NULL || *type_out == string->map()->instance_type());
3043 return string;
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00003044}
3045
3046
3047uint16_t StringCharacterStream::GetNext() {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00003048 ASSERT(buffer8_ != NULL && end_ != NULL);
3049 // Advance cursor if needed.
3050 // TODO(dcarney): Ensure uses of the api call HasMore first and avoid this.
3051 if (buffer8_ == end_) HasMore();
3052 ASSERT(buffer8_ < end_);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00003053 return is_one_byte_ ? *buffer8_++ : *buffer16_++;
3054}
3055
3056
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00003057StringCharacterStream::StringCharacterStream(String* string,
3058 ConsStringIteratorOp* op,
3059 unsigned offset)
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003060 : is_one_byte_(false),
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00003061 op_(op) {
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00003062 Reset(string, offset);
3063}
3064
3065
3066void StringCharacterStream::Reset(String* string, unsigned offset) {
3067 op_->Reset();
3068 buffer8_ = NULL;
3069 end_ = NULL;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003070 int32_t type = string->map()->instance_type();
3071 unsigned length = string->length();
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00003072 String::Visit(string, offset, *this, *op_, type, length);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00003073}
3074
3075
3076bool StringCharacterStream::HasMore() {
3077 if (buffer8_ != end_) return true;
3078 if (!op_->HasMore()) return false;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003079 unsigned length;
3080 int32_t type;
3081 String* string = op_->ContinueOperation(&type, &length);
3082 if (string == NULL) return false;
3083 ASSERT(!string->IsConsString());
3084 ASSERT(string->length() != 0);
3085 ConsStringNullOp null_op;
3086 String::Visit(string, 0, *this, null_op, type, length);
3087 ASSERT(buffer8_ != end_);
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00003088 return true;
3089}
3090
3091
3092void StringCharacterStream::VisitOneByteString(
3093 const uint8_t* chars, unsigned length) {
3094 is_one_byte_ = true;
3095 buffer8_ = chars;
3096 end_ = chars + length;
3097}
3098
3099
3100void StringCharacterStream::VisitTwoByteString(
3101 const uint16_t* chars, unsigned length) {
3102 is_one_byte_ = false;
3103 buffer16_ = chars;
3104 end_ = reinterpret_cast<const uint8_t*>(chars + length);
3105}
3106
3107
ager@chromium.orgac091b72010-05-05 07:34:42 +00003108void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003109 set_finger_index(kEntriesIndex);
3110 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00003111}
3112
3113
3114void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003115 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00003116 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00003117 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003118 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00003119 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00003120 MakeZeroSize();
3121}
3122
3123
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003124int JSFunctionResultCache::size() {
3125 return Smi::cast(get(kCacheSizeIndex))->value();
3126}
3127
3128
3129void JSFunctionResultCache::set_size(int size) {
3130 set(kCacheSizeIndex, Smi::FromInt(size));
3131}
3132
3133
3134int JSFunctionResultCache::finger_index() {
3135 return Smi::cast(get(kFingerIndex))->value();
3136}
3137
3138
3139void JSFunctionResultCache::set_finger_index(int finger_index) {
3140 set(kFingerIndex, Smi::FromInt(finger_index));
3141}
3142
3143
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003144byte ByteArray::get(int index) {
3145 ASSERT(index >= 0 && index < this->length());
3146 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
3147}
3148
3149
3150void ByteArray::set(int index, byte value) {
3151 ASSERT(index >= 0 && index < this->length());
3152 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
3153}
3154
3155
3156int ByteArray::get_int(int index) {
3157 ASSERT(index >= 0 && (index * kIntSize) < this->length());
3158 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
3159}
3160
3161
3162ByteArray* ByteArray::FromDataStartAddress(Address address) {
3163 ASSERT_TAG_ALIGNED(address);
3164 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
3165}
3166
3167
3168Address ByteArray::GetDataStartAddress() {
3169 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
3170}
3171
3172
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003173uint8_t* ExternalPixelArray::external_pixel_pointer() {
3174 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003175}
3176
3177
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003178uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003179 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003180 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003181 return ptr[index];
3182}
3183
3184
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003185MaybeObject* ExternalPixelArray::get(int index) {
3186 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3187}
3188
3189
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003190void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003191 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003192 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003193 ptr[index] = value;
3194}
3195
3196
ager@chromium.org3811b432009-10-28 14:53:37 +00003197void* ExternalArray::external_pointer() {
3198 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
3199 return reinterpret_cast<void*>(ptr);
3200}
3201
3202
3203void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
3204 intptr_t ptr = reinterpret_cast<intptr_t>(value);
3205 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
3206}
3207
3208
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003209int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003210 ASSERT((index >= 0) && (index < this->length()));
3211 int8_t* ptr = static_cast<int8_t*>(external_pointer());
3212 return ptr[index];
3213}
3214
3215
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003216MaybeObject* ExternalByteArray::get(int index) {
3217 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3218}
3219
3220
ager@chromium.org3811b432009-10-28 14:53:37 +00003221void ExternalByteArray::set(int index, int8_t value) {
3222 ASSERT((index >= 0) && (index < this->length()));
3223 int8_t* ptr = static_cast<int8_t*>(external_pointer());
3224 ptr[index] = value;
3225}
3226
3227
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003228uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003229 ASSERT((index >= 0) && (index < this->length()));
3230 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
3231 return ptr[index];
3232}
3233
3234
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003235MaybeObject* ExternalUnsignedByteArray::get(int index) {
3236 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3237}
3238
3239
ager@chromium.org3811b432009-10-28 14:53:37 +00003240void ExternalUnsignedByteArray::set(int index, uint8_t value) {
3241 ASSERT((index >= 0) && (index < this->length()));
3242 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
3243 ptr[index] = value;
3244}
3245
3246
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003247int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003248 ASSERT((index >= 0) && (index < this->length()));
3249 int16_t* ptr = static_cast<int16_t*>(external_pointer());
3250 return ptr[index];
3251}
3252
3253
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003254MaybeObject* ExternalShortArray::get(int index) {
3255 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3256}
3257
3258
ager@chromium.org3811b432009-10-28 14:53:37 +00003259void ExternalShortArray::set(int index, int16_t value) {
3260 ASSERT((index >= 0) && (index < this->length()));
3261 int16_t* ptr = static_cast<int16_t*>(external_pointer());
3262 ptr[index] = value;
3263}
3264
3265
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003266uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003267 ASSERT((index >= 0) && (index < this->length()));
3268 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
3269 return ptr[index];
3270}
3271
3272
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003273MaybeObject* ExternalUnsignedShortArray::get(int index) {
3274 return Smi::FromInt(static_cast<int>(get_scalar(index)));
3275}
3276
3277
ager@chromium.org3811b432009-10-28 14:53:37 +00003278void ExternalUnsignedShortArray::set(int index, uint16_t value) {
3279 ASSERT((index >= 0) && (index < this->length()));
3280 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
3281 ptr[index] = value;
3282}
3283
3284
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003285int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003286 ASSERT((index >= 0) && (index < this->length()));
3287 int32_t* ptr = static_cast<int32_t*>(external_pointer());
3288 return ptr[index];
3289}
3290
3291
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003292MaybeObject* ExternalIntArray::get(int index) {
3293 return GetHeap()->NumberFromInt32(get_scalar(index));
3294}
3295
3296
ager@chromium.org3811b432009-10-28 14:53:37 +00003297void ExternalIntArray::set(int index, int32_t value) {
3298 ASSERT((index >= 0) && (index < this->length()));
3299 int32_t* ptr = static_cast<int32_t*>(external_pointer());
3300 ptr[index] = value;
3301}
3302
3303
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003304uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003305 ASSERT((index >= 0) && (index < this->length()));
3306 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
3307 return ptr[index];
3308}
3309
3310
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003311MaybeObject* ExternalUnsignedIntArray::get(int index) {
3312 return GetHeap()->NumberFromUint32(get_scalar(index));
3313}
3314
3315
ager@chromium.org3811b432009-10-28 14:53:37 +00003316void ExternalUnsignedIntArray::set(int index, uint32_t value) {
3317 ASSERT((index >= 0) && (index < this->length()));
3318 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
3319 ptr[index] = value;
3320}
3321
3322
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003323float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00003324 ASSERT((index >= 0) && (index < this->length()));
3325 float* ptr = static_cast<float*>(external_pointer());
3326 return ptr[index];
3327}
3328
3329
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003330MaybeObject* ExternalFloatArray::get(int index) {
3331 return GetHeap()->NumberFromDouble(get_scalar(index));
3332}
3333
3334
ager@chromium.org3811b432009-10-28 14:53:37 +00003335void ExternalFloatArray::set(int index, float value) {
3336 ASSERT((index >= 0) && (index < this->length()));
3337 float* ptr = static_cast<float*>(external_pointer());
3338 ptr[index] = value;
3339}
3340
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00003341
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003342double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003343 ASSERT((index >= 0) && (index < this->length()));
3344 double* ptr = static_cast<double*>(external_pointer());
3345 return ptr[index];
3346}
3347
3348
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003349MaybeObject* ExternalDoubleArray::get(int index) {
3350 return GetHeap()->NumberFromDouble(get_scalar(index));
3351}
3352
3353
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003354void ExternalDoubleArray::set(int index, double value) {
3355 ASSERT((index >= 0) && (index < this->length()));
3356 double* ptr = static_cast<double*>(external_pointer());
3357 ptr[index] = value;
3358}
3359
3360
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00003361int Map::visitor_id() {
3362 return READ_BYTE_FIELD(this, kVisitorIdOffset);
3363}
3364
3365
3366void Map::set_visitor_id(int id) {
3367 ASSERT(0 <= id && id < 256);
3368 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
3369}
3370
ager@chromium.org3811b432009-10-28 14:53:37 +00003371
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003372int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00003373 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
3374}
3375
3376
3377int Map::inobject_properties() {
3378 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003379}
3380
3381
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003382int Map::pre_allocated_property_fields() {
3383 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
3384}
3385
3386
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003387int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003388 int instance_size = map->instance_size();
3389 if (instance_size != kVariableSizeSentinel) return instance_size;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003390 // Only inline the most frequent cases.
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00003391 int instance_type = static_cast<int>(map->instance_type());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003392 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00003393 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003394 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00003395 if (instance_type == ASCII_STRING_TYPE ||
3396 instance_type == ASCII_INTERNALIZED_STRING_TYPE) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003397 return SeqOneByteString::SizeFor(
3398 reinterpret_cast<SeqOneByteString*>(this)->length());
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003399 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003400 if (instance_type == BYTE_ARRAY_TYPE) {
3401 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
3402 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003403 if (instance_type == FREE_SPACE_TYPE) {
3404 return reinterpret_cast<FreeSpace*>(this)->size();
3405 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00003406 if (instance_type == STRING_TYPE ||
3407 instance_type == INTERNALIZED_STRING_TYPE) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003408 return SeqTwoByteString::SizeFor(
3409 reinterpret_cast<SeqTwoByteString*>(this)->length());
3410 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003411 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
3412 return FixedDoubleArray::SizeFor(
3413 reinterpret_cast<FixedDoubleArray*>(this)->length());
3414 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003415 ASSERT(instance_type == CODE_TYPE);
3416 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003417}
3418
3419
3420void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003421 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003422 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003423 ASSERT(0 <= value && value < 256);
3424 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
3425}
3426
3427
ager@chromium.org7c537e22008-10-16 08:43:32 +00003428void Map::set_inobject_properties(int value) {
3429 ASSERT(0 <= value && value < 256);
3430 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
3431}
3432
3433
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003434void Map::set_pre_allocated_property_fields(int value) {
3435 ASSERT(0 <= value && value < 256);
3436 WRITE_BYTE_FIELD(this,
3437 kPreAllocatedPropertyFieldsOffset,
3438 static_cast<byte>(value));
3439}
3440
3441
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003442InstanceType Map::instance_type() {
3443 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
3444}
3445
3446
3447void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003448 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
3449}
3450
3451
3452int Map::unused_property_fields() {
3453 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
3454}
3455
3456
3457void Map::set_unused_property_fields(int value) {
3458 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
3459}
3460
3461
3462byte Map::bit_field() {
3463 return READ_BYTE_FIELD(this, kBitFieldOffset);
3464}
3465
3466
3467void Map::set_bit_field(byte value) {
3468 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
3469}
3470
3471
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00003472byte Map::bit_field2() {
3473 return READ_BYTE_FIELD(this, kBitField2Offset);
3474}
3475
3476
3477void Map::set_bit_field2(byte value) {
3478 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
3479}
3480
3481
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003482void Map::set_non_instance_prototype(bool value) {
3483 if (value) {
3484 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
3485 } else {
3486 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
3487 }
3488}
3489
3490
3491bool Map::has_non_instance_prototype() {
3492 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
3493}
3494
3495
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003496void Map::set_function_with_prototype(bool value) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003497 set_bit_field3(FunctionWithPrototype::update(bit_field3(), value));
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003498}
3499
3500
3501bool Map::function_with_prototype() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003502 return FunctionWithPrototype::decode(bit_field3());
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003503}
3504
3505
ager@chromium.org870a0b62008-11-04 11:43:05 +00003506void Map::set_is_access_check_needed(bool access_check_needed) {
3507 if (access_check_needed) {
3508 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
3509 } else {
3510 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
3511 }
3512}
3513
3514
3515bool Map::is_access_check_needed() {
3516 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
3517}
3518
3519
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003520void Map::set_is_extensible(bool value) {
3521 if (value) {
3522 set_bit_field2(bit_field2() | (1 << kIsExtensible));
3523 } else {
3524 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
3525 }
3526}
3527
3528bool Map::is_extensible() {
3529 return ((1 << kIsExtensible) & bit_field2()) != 0;
3530}
3531
3532
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003533void Map::set_attached_to_shared_function_info(bool value) {
3534 if (value) {
3535 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
3536 } else {
3537 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
3538 }
3539}
3540
3541bool Map::attached_to_shared_function_info() {
3542 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
3543}
3544
3545
3546void Map::set_is_shared(bool value) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003547 set_bit_field3(IsShared::update(bit_field3(), value));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003548}
3549
erik.corry@gmail.com88767242012-08-08 14:43:45 +00003550
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003551bool Map::is_shared() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003552 return IsShared::decode(bit_field3());
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003553}
3554
3555
erik.corry@gmail.com88767242012-08-08 14:43:45 +00003556void Map::set_dictionary_map(bool value) {
3557 set_bit_field3(DictionaryMap::update(bit_field3(), value));
3558}
3559
3560
3561bool Map::is_dictionary_map() {
3562 return DictionaryMap::decode(bit_field3());
3563}
3564
3565
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003566Code::Flags Code::flags() {
3567 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
3568}
3569
3570
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00003571inline bool Map::CanTrackAllocationSite() {
3572 return instance_type() == JS_ARRAY_TYPE;
3573}
3574
3575
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00003576void Map::set_owns_descriptors(bool is_shared) {
3577 set_bit_field3(OwnsDescriptors::update(bit_field3(), is_shared));
3578}
3579
3580
3581bool Map::owns_descriptors() {
3582 return OwnsDescriptors::decode(bit_field3());
3583}
3584
3585
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00003586void Map::set_is_observed(bool is_observed) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00003587 ASSERT(instance_type() < FIRST_JS_OBJECT_TYPE ||
3588 instance_type() > LAST_JS_OBJECT_TYPE ||
3589 has_slow_elements_kind() || has_external_array_elements());
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00003590 set_bit_field3(IsObserved::update(bit_field3(), is_observed));
3591}
3592
3593
3594bool Map::is_observed() {
3595 return IsObserved::decode(bit_field3());
3596}
3597
3598
danno@chromium.orgf005df62013-04-30 16:36:45 +00003599void Map::deprecate() {
3600 set_bit_field3(Deprecated::update(bit_field3(), true));
3601}
3602
3603
3604bool Map::is_deprecated() {
3605 if (!FLAG_track_fields) return false;
3606 return Deprecated::decode(bit_field3());
3607}
3608
3609
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00003610void Map::freeze() {
3611 set_bit_field3(IsFrozen::update(bit_field3(), true));
3612}
3613
3614
3615bool Map::is_frozen() {
3616 return IsFrozen::decode(bit_field3());
3617}
3618
3619
danno@chromium.orgf005df62013-04-30 16:36:45 +00003620bool Map::CanBeDeprecated() {
3621 int descriptor = LastAdded();
3622 for (int i = 0; i <= descriptor; i++) {
3623 PropertyDetails details = instance_descriptors()->GetDetails(i);
danno@chromium.org1fd77d52013-06-07 16:01:45 +00003624 if (FLAG_track_fields && details.representation().IsNone()) {
3625 return true;
3626 }
danno@chromium.orgf005df62013-04-30 16:36:45 +00003627 if (FLAG_track_fields && details.representation().IsSmi()) {
3628 return true;
3629 }
3630 if (FLAG_track_double_fields && details.representation().IsDouble()) {
3631 return true;
3632 }
ulan@chromium.org906e2fb2013-05-14 08:14:38 +00003633 if (FLAG_track_heap_object_fields &&
3634 details.representation().IsHeapObject()) {
3635 return true;
3636 }
dslomov@chromium.orgb752d402013-06-18 11:54:54 +00003637 if (FLAG_track_fields && details.type() == CONSTANT_FUNCTION) {
3638 return true;
3639 }
danno@chromium.orgf005df62013-04-30 16:36:45 +00003640 }
3641 return false;
3642}
3643
3644
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003645void Map::NotifyLeafMapLayoutChange() {
3646 dependent_code()->DeoptimizeDependentCodeGroup(
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003647 GetIsolate(),
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003648 DependentCode::kPrototypeCheckGroup);
3649}
3650
3651
3652bool Map::CanOmitPrototypeChecks() {
3653 return !HasTransitionArray() && !is_dictionary_map() &&
3654 FLAG_omit_prototype_checks_for_leaf_maps;
3655}
3656
3657
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003658int DependentCode::number_of_entries(DependencyGroup group) {
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003659 if (length() == 0) return 0;
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003660 return Smi::cast(get(group))->value();
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003661}
3662
3663
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003664void DependentCode::set_number_of_entries(DependencyGroup group, int value) {
3665 set(group, Smi::FromInt(value));
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003666}
3667
3668
danno@chromium.org41728482013-06-12 22:31:22 +00003669bool DependentCode::is_code_at(int i) {
3670 return get(kCodesStartIndex + i)->IsCode();
3671}
3672
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003673Code* DependentCode::code_at(int i) {
3674 return Code::cast(get(kCodesStartIndex + i));
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003675}
3676
3677
danno@chromium.org41728482013-06-12 22:31:22 +00003678CompilationInfo* DependentCode::compilation_info_at(int i) {
3679 return reinterpret_cast<CompilationInfo*>(
3680 Foreign::cast(get(kCodesStartIndex + i))->foreign_address());
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003681}
3682
3683
danno@chromium.org41728482013-06-12 22:31:22 +00003684void DependentCode::set_object_at(int i, Object* object) {
3685 set(kCodesStartIndex + i, object);
3686}
3687
3688
3689Object* DependentCode::object_at(int i) {
3690 return get(kCodesStartIndex + i);
3691}
3692
3693
3694Object** DependentCode::slot_at(int i) {
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003695 return HeapObject::RawField(
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003696 this, FixedArray::OffsetOfElementAt(kCodesStartIndex + i));
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003697}
3698
3699
danno@chromium.org41728482013-06-12 22:31:22 +00003700void DependentCode::clear_at(int i) {
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003701 set_undefined(kCodesStartIndex + i);
3702}
3703
3704
danno@chromium.org41728482013-06-12 22:31:22 +00003705void DependentCode::copy(int from, int to) {
3706 set(kCodesStartIndex + to, get(kCodesStartIndex + from));
3707}
3708
3709
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003710void DependentCode::ExtendGroup(DependencyGroup group) {
3711 GroupStartIndexes starts(this);
3712 for (int g = kGroupCount - 1; g > group; g--) {
3713 if (starts.at(g) < starts.at(g + 1)) {
danno@chromium.org41728482013-06-12 22:31:22 +00003714 copy(starts.at(g), starts.at(g + 1));
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003715 }
3716 }
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003717}
3718
3719
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003720void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003721 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003722 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003723 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
3724 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003725 ExtractArgumentsCountFromFlags(flags) >= 0);
3726 WRITE_INT_FIELD(this, kFlagsOffset, flags);
3727}
3728
3729
3730Code::Kind Code::kind() {
3731 return ExtractKindFromFlags(flags());
3732}
3733
3734
kasper.lund7276f142008-07-30 08:49:36 +00003735InlineCacheState Code::ic_state() {
3736 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003737 // Only allow uninitialized or debugger states for non-IC code
3738 // objects. This is used in the debugger to determine whether or not
3739 // a call to code object has been replaced with a debug break call.
3740 ASSERT(is_inline_cache_stub() ||
3741 result == UNINITIALIZED ||
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00003742 result == DEBUG_STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003743 return result;
3744}
3745
3746
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003747Code::ExtraICState Code::extra_ic_state() {
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00003748 ASSERT(is_inline_cache_stub() || ic_state() == DEBUG_STUB);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003749 return ExtractExtraICStateFromFlags(flags());
3750}
3751
3752
danno@chromium.orgca29dd82013-04-26 11:59:48 +00003753Code::ExtraICState Code::extended_extra_ic_state() {
3754 ASSERT(is_inline_cache_stub() || ic_state() == DEBUG_STUB);
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +00003755 ASSERT(needs_extended_extra_ic_state(kind()));
danno@chromium.orgca29dd82013-04-26 11:59:48 +00003756 return ExtractExtendedExtraICStateFromFlags(flags());
3757}
3758
3759
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00003760Code::StubType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003761 return ExtractTypeFromFlags(flags());
3762}
3763
3764
3765int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003766 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003767 return ExtractArgumentsCountFromFlags(flags());
3768}
3769
3770
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +00003771inline bool Code::is_crankshafted() {
3772 return IsCrankshaftedField::decode(
3773 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
3774}
3775
3776
3777inline void Code::set_is_crankshafted(bool value) {
3778 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3779 int updated = IsCrankshaftedField::update(previous, value);
3780 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
3781}
3782
3783
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003784int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003785 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003786 kind() == UNARY_OP_IC ||
3787 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003788 kind() == COMPARE_IC ||
danno@chromium.orgca29dd82013-04-26 11:59:48 +00003789 kind() == COMPARE_NIL_IC ||
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00003790 kind() == LOAD_IC ||
3791 kind() == KEYED_LOAD_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003792 kind() == TO_BOOLEAN_IC);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003793 return StubMajorKeyField::decode(
3794 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasper.lund7276f142008-07-30 08:49:36 +00003795}
3796
3797
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003798void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003799 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003800 kind() == UNARY_OP_IC ||
3801 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003802 kind() == COMPARE_IC ||
danno@chromium.orgca29dd82013-04-26 11:59:48 +00003803 kind() == COMPARE_NIL_IC ||
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00003804 kind() == LOAD_IC ||
3805 kind() == KEYED_LOAD_IC ||
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +00003806 kind() == STORE_IC ||
3807 kind() == KEYED_STORE_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003808 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00003809 ASSERT(0 <= major && major < 256);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003810 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3811 int updated = StubMajorKeyField::update(previous, major);
3812 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003813}
3814
3815
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003816bool Code::is_pregenerated() {
danno@chromium.orgca29dd82013-04-26 11:59:48 +00003817 return (kind() == STUB && IsPregeneratedField::decode(flags()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003818}
3819
3820
3821void Code::set_is_pregenerated(bool value) {
3822 ASSERT(kind() == STUB);
3823 Flags f = flags();
3824 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3825 set_flags(f);
3826}
3827
3828
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003829bool Code::optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003830 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003831 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3832}
3833
3834
3835void Code::set_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003836 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003837 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3838}
3839
3840
3841bool Code::has_deoptimization_support() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003842 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003843 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3844 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003845}
3846
3847
3848void Code::set_has_deoptimization_support(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003849 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003850 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3851 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3852 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3853}
3854
3855
3856bool Code::has_debug_break_slots() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003857 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003858 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3859 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3860}
3861
3862
3863void Code::set_has_debug_break_slots(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003864 ASSERT_EQ(FUNCTION, kind());
lrn@chromium.org34e60782011-09-15 07:25:40 +00003865 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3866 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3867 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003868}
3869
3870
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003871bool Code::is_compiled_optimizable() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003872 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003873 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3874 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3875}
3876
3877
3878void Code::set_compiled_optimizable(bool value) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003879 ASSERT_EQ(FUNCTION, kind());
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003880 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3881 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3882 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3883}
3884
3885
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003886int Code::allow_osr_at_loop_nesting_level() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003887 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003888 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3889}
3890
3891
3892void Code::set_allow_osr_at_loop_nesting_level(int level) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003893 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003894 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3895 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3896}
3897
3898
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003899int Code::profiler_ticks() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003900 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003901 return READ_BYTE_FIELD(this, kProfilerTicksOffset);
3902}
3903
3904
3905void Code::set_profiler_ticks(int ticks) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003906 ASSERT_EQ(FUNCTION, kind());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00003907 ASSERT(ticks < 256);
3908 WRITE_BYTE_FIELD(this, kProfilerTicksOffset, ticks);
3909}
3910
3911
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003912unsigned Code::stack_slots() {
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +00003913 ASSERT(is_crankshafted());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003914 return StackSlotsField::decode(
3915 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003916}
3917
3918
3919void Code::set_stack_slots(unsigned slots) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003920 CHECK(slots <= (1 << kStackSlotsBitCount));
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +00003921 ASSERT(is_crankshafted());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003922 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
3923 int updated = StackSlotsField::update(previous, slots);
3924 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003925}
3926
3927
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003928unsigned Code::safepoint_table_offset() {
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +00003929 ASSERT(is_crankshafted());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003930 return SafepointTableOffsetField::decode(
3931 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003932}
3933
3934
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003935void Code::set_safepoint_table_offset(unsigned offset) {
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003936 CHECK(offset <= (1 << kSafepointTableOffsetBitCount));
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +00003937 ASSERT(is_crankshafted());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003938 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003939 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
3940 int updated = SafepointTableOffsetField::update(previous, offset);
3941 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003942}
3943
3944
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003945unsigned Code::back_edge_table_offset() {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003946 ASSERT_EQ(FUNCTION, kind());
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003947 return BackEdgeTableOffsetField::decode(
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003948 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003949}
3950
3951
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003952void Code::set_back_edge_table_offset(unsigned offset) {
fschneider@chromium.org7d10be52012-04-10 12:30:14 +00003953 ASSERT_EQ(FUNCTION, kind());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003954 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003955 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003956 int updated = BackEdgeTableOffsetField::update(previous, offset);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003957 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003958}
3959
3960
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003961bool Code::back_edges_patched_for_osr() {
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00003962 ASSERT_EQ(FUNCTION, kind());
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003963 return BackEdgesPatchedForOSRField::decode(
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00003964 READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
3965}
3966
3967
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003968void Code::set_back_edges_patched_for_osr(bool value) {
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00003969 ASSERT_EQ(FUNCTION, kind());
3970 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003971 int updated = BackEdgesPatchedForOSRField::update(previous, value);
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00003972 WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
3973}
3974
3975
3976
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003977CheckType Code::check_type() {
3978 ASSERT(is_call_stub() || is_keyed_call_stub());
3979 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3980 return static_cast<CheckType>(type);
3981}
3982
3983
3984void Code::set_check_type(CheckType value) {
3985 ASSERT(is_call_stub() || is_keyed_call_stub());
3986 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3987}
3988
3989
danno@chromium.org40cb8782011-05-25 07:58:50 +00003990byte Code::unary_op_type() {
3991 ASSERT(is_unary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003992 return UnaryOpTypeField::decode(
3993 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003994}
3995
3996
danno@chromium.org40cb8782011-05-25 07:58:50 +00003997void Code::set_unary_op_type(byte value) {
3998 ASSERT(is_unary_op_stub());
danno@chromium.org81cac2b2012-07-10 11:28:27 +00003999 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4000 int updated = UnaryOpTypeField::update(previous, value);
4001 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00004002}
4003
4004
ricow@chromium.org9fa09672011-07-25 11:05:35 +00004005byte Code::to_boolean_state() {
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +00004006 return extended_extra_ic_state();
ricow@chromium.org9fa09672011-07-25 11:05:35 +00004007}
4008
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004009
4010bool Code::has_function_cache() {
4011 ASSERT(kind() == STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004012 return HasFunctionCacheField::decode(
4013 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004014}
4015
4016
4017void Code::set_has_function_cache(bool flag) {
4018 ASSERT(kind() == STUB);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004019 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4020 int updated = HasFunctionCacheField::update(previous, flag);
4021 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004022}
4023
4024
yangguo@chromium.org003650e2013-01-24 16:31:08 +00004025bool Code::marked_for_deoptimization() {
4026 ASSERT(kind() == OPTIMIZED_FUNCTION);
4027 return MarkedForDeoptimizationField::decode(
4028 READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
4029}
4030
4031
4032void Code::set_marked_for_deoptimization(bool flag) {
4033 ASSERT(kind() == OPTIMIZED_FUNCTION);
4034 int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
4035 int updated = MarkedForDeoptimizationField::update(previous, flag);
4036 WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
4037}
4038
4039
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004040bool Code::is_inline_cache_stub() {
4041 Kind kind = this->kind();
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00004042 switch (kind) {
4043#define CASE(name) case name: return true;
4044 IC_KIND_LIST(CASE)
4045#undef CASE
4046 default: return false;
4047 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004048}
4049
4050
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00004051bool Code::is_debug_break() {
4052 return ic_state() == DEBUG_STUB && extra_ic_state() == DEBUG_BREAK;
4053}
4054
4055
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004056Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00004057 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00004058 ExtraICState extra_ic_state,
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00004059 StubType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00004060 int argc,
4061 InlineCacheHolderFlag holder) {
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00004062 ASSERT(argc <= Code::kMaxArguments);
danno@chromium.orgca29dd82013-04-26 11:59:48 +00004063 // Since the extended extra ic state overlaps with the argument count
4064 // for CALL_ICs, do so checks to make sure that they don't interfere.
4065 ASSERT((kind != Code::CALL_IC &&
4066 kind != Code::KEYED_CALL_IC) ||
4067 (ExtraICStateField::encode(extra_ic_state) | true));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004068 // Compute the bit mask.
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00004069 unsigned int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004070 | ICStateField::encode(ic_state)
4071 | TypeField::encode(type)
danno@chromium.orgca29dd82013-04-26 11:59:48 +00004072 | ExtendedExtraICStateField::encode(extra_ic_state)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004073 | CacheHolderField::encode(holder);
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +00004074 if (!Code::needs_extended_extra_ic_state(kind)) {
danno@chromium.orgca29dd82013-04-26 11:59:48 +00004075 bits |= (argc << kArgumentsCountShift);
4076 }
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004077 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004078}
4079
4080
4081Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00004082 ExtraICState extra_ic_state,
hpayer@chromium.org8432c912013-02-28 15:55:26 +00004083 StubType type,
4084 int argc,
4085 InlineCacheHolderFlag holder) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00004086 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004087}
4088
4089
4090Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004091 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004092}
4093
4094
kasper.lund7276f142008-07-30 08:49:36 +00004095InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004096 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004097}
4098
4099
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00004100Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004101 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00004102}
4103
4104
danno@chromium.orgca29dd82013-04-26 11:59:48 +00004105Code::ExtraICState Code::ExtractExtendedExtraICStateFromFlags(
4106 Flags flags) {
4107 return ExtendedExtraICStateField::decode(flags);
4108}
4109
4110
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00004111Code::StubType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004112 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004113}
4114
4115
4116int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00004117 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004118}
4119
4120
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00004121InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004122 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00004123}
4124
4125
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004126Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004127 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004128 return static_cast<Flags>(bits);
4129}
4130
4131
ager@chromium.org8bb60582008-12-11 12:02:20 +00004132Code* Code::GetCodeFromTargetAddress(Address address) {
4133 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
4134 // GetCodeFromTargetAddress might be called when marking objects during mark
4135 // sweep. reinterpret_cast is therefore used instead of the more appropriate
4136 // Code::cast. Code::cast does not work when the object's map is
4137 // marked.
4138 Code* result = reinterpret_cast<Code*>(code);
4139 return result;
4140}
4141
4142
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004143Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
4144 return HeapObject::
4145 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
4146}
4147
4148
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004149Object* Map::prototype() {
4150 return READ_FIELD(this, kPrototypeOffset);
4151}
4152
4153
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004154void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004155 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004156 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004157 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00004158}
4159
4160
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004161// If the descriptor is using the empty transition array, install a new empty
4162// transition array that will have place for an element transition.
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004163static MaybeObject* EnsureHasTransitionArray(Map* map) {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004164 TransitionArray* transitions;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00004165 MaybeObject* maybe_transitions;
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004166 if (!map->HasTransitionArray()) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004167 maybe_transitions = TransitionArray::Allocate(0);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00004168 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
4169 transitions->set_back_pointer_storage(map->GetBackPointer());
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004170 } else if (!map->transitions()->IsFullTransitionArray()) {
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004171 maybe_transitions = map->transitions()->ExtendToFullTransitionArray();
4172 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
4173 } else {
4174 return map;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00004175 }
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004176 map->set_transitions(transitions);
4177 return transitions;
4178}
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004179
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004180
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004181void Map::InitializeDescriptors(DescriptorArray* descriptors) {
verwaest@chromium.org652f4fa2012-10-08 08:48:51 +00004182 int len = descriptors->number_of_descriptors();
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004183 set_instance_descriptors(descriptors);
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00004184 SetNumberOfOwnDescriptors(len);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004185}
4186
4187
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004188ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset)
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004189SMI_ACCESSORS(Map, bit_field3, kBitField3Offset)
danno@chromium.org40cb8782011-05-25 07:58:50 +00004190
4191
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004192void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004193 Object* back_pointer = GetBackPointer();
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00004194
4195 if (Heap::ShouldZapGarbage() && HasTransitionArray()) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004196 ZapTransitions();
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00004197 }
svenpanne@chromium.orgc859c4f2012-10-15 11:51:39 +00004198
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004199 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, back_pointer);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004200 CONDITIONAL_WRITE_BARRIER(
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004201 heap, this, kTransitionsOrBackPointerOffset, back_pointer, mode);
jkummerow@chromium.org7a6fc812012-06-27 11:12:38 +00004202}
4203
4204
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004205void Map::AppendDescriptor(Descriptor* desc,
4206 const DescriptorArray::WhitenessWitness& witness) {
4207 DescriptorArray* descriptors = instance_descriptors();
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004208 int number_of_own_descriptors = NumberOfOwnDescriptors();
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00004209 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors);
4210 descriptors->Append(desc, witness);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004211 SetNumberOfOwnDescriptors(number_of_own_descriptors + 1);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004212}
4213
danno@chromium.org40cb8782011-05-25 07:58:50 +00004214
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004215Object* Map::GetBackPointer() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004216 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004217 if (object->IsDescriptorArray()) {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004218 return TransitionArray::cast(object)->back_pointer_storage();
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004219 } else {
4220 ASSERT(object->IsMap() || object->IsUndefined());
4221 return object;
4222 }
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004223}
4224
4225
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004226bool Map::HasElementsTransition() {
4227 return HasTransitionArray() && transitions()->HasElementsTransition();
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004228}
4229
4230
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004231bool Map::HasTransitionArray() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004232 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
4233 return object->IsTransitionArray();
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004234}
4235
4236
4237Map* Map::elements_transition_map() {
4238 return transitions()->elements_transition();
4239}
4240
4241
verwaest@chromium.orgb6d052d2012-07-27 08:03:27 +00004242bool Map::CanHaveMoreTransitions() {
4243 if (!HasTransitionArray()) return true;
4244 return FixedArray::SizeFor(transitions()->length() +
4245 TransitionArray::kTransitionSize)
4246 <= Page::kMaxNonCodeHeapObjectSize;
4247}
4248
4249
ulan@chromium.org750145a2013-03-07 15:14:13 +00004250MaybeObject* Map::AddTransition(Name* key,
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00004251 Map* target,
4252 SimpleTransitionFlag flag) {
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004253 if (HasTransitionArray()) return transitions()->CopyInsert(key, target);
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004254 return TransitionArray::NewWith(flag, key, target, GetBackPointer());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004255}
4256
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004257
4258void Map::SetTransition(int transition_index, Map* target) {
4259 transitions()->SetTarget(transition_index, target);
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00004260}
4261
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004262
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +00004263Map* Map::GetTransition(int transition_index) {
4264 return transitions()->GetTarget(transition_index);
4265}
4266
4267
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004268MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004269 MaybeObject* allow_elements = EnsureHasTransitionArray(this);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004270 if (allow_elements->IsFailure()) return allow_elements;
4271 transitions()->set_elements_transition(transitioned_map);
4272 return this;
4273}
4274
4275
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004276FixedArray* Map::GetPrototypeTransitions() {
4277 if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
4278 if (!transitions()->HasPrototypeTransitions()) {
4279 return GetHeap()->empty_fixed_array();
4280 }
4281 return transitions()->GetPrototypeTransitions();
4282}
4283
4284
4285MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00004286 MaybeObject* allow_prototype = EnsureHasTransitionArray(this);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004287 if (allow_prototype->IsFailure()) return allow_prototype;
4288#ifdef DEBUG
4289 if (HasPrototypeTransitions()) {
4290 ASSERT(GetPrototypeTransitions() != proto_transitions);
4291 ZapPrototypeTransitions();
4292 }
4293#endif
4294 transitions()->SetPrototypeTransitions(proto_transitions);
4295 return this;
4296}
4297
4298
4299bool Map::HasPrototypeTransitions() {
4300 return HasTransitionArray() && transitions()->HasPrototypeTransitions();
4301}
4302
4303
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004304TransitionArray* Map::transitions() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004305 ASSERT(HasTransitionArray());
4306 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
4307 return TransitionArray::cast(object);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004308}
4309
4310
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004311void Map::set_transitions(TransitionArray* transition_array,
4312 WriteBarrierMode mode) {
jkummerow@chromium.org91efda92013-03-25 16:32:26 +00004313 // Transition arrays are not shared. When one is replaced, it should not
4314 // keep referenced objects alive, so we zap it.
4315 // When there is another reference to the array somewhere (e.g. a handle),
4316 // not zapping turns from a waste of memory into a source of crashes.
4317 if (HasTransitionArray()) {
4318 ASSERT(transitions() != transition_array);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00004319 ZapTransitions();
4320 }
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004321
4322 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, transition_array);
4323 CONDITIONAL_WRITE_BARRIER(
4324 GetHeap(), this, kTransitionsOrBackPointerOffset, transition_array, mode);
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004325}
4326
4327
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004328void Map::init_back_pointer(Object* undefined) {
4329 ASSERT(undefined->IsUndefined());
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004330 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, undefined);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004331}
4332
4333
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004334void Map::SetBackPointer(Object* value, WriteBarrierMode mode) {
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004335 ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE);
4336 ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) ||
4337 (value->IsMap() && GetBackPointer()->IsUndefined()));
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004338 Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
4339 if (object->IsTransitionArray()) {
4340 TransitionArray::cast(object)->set_back_pointer_storage(value);
verwaest@chromium.org753aee42012-07-17 16:15:42 +00004341 } else {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004342 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, value);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004343 CONDITIONAL_WRITE_BARRIER(
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004344 GetHeap(), this, kTransitionsOrBackPointerOffset, value, mode);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00004345 }
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004346}
4347
4348
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004349// Can either be Smi (no transitions), normal transition array, or a transition
4350// array with the header overwritten as a Smi (thus iterating).
4351TransitionArray* Map::unchecked_transition_array() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +00004352 Object* object = *HeapObject::RawField(this,
4353 Map::kTransitionsOrBackPointerOffset);
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004354 TransitionArray* transition_array = static_cast<TransitionArray*>(object);
4355 return transition_array;
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004356}
4357
4358
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004359HeapObject* Map::UncheckedPrototypeTransitions() {
4360 ASSERT(HasTransitionArray());
4361 ASSERT(unchecked_transition_array()->HasPrototypeTransitions());
4362 return unchecked_transition_array()->UncheckedPrototypeTransitions();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004363}
4364
4365
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004366ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004367ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004368ACCESSORS(Map, constructor, Object, kConstructorOffset)
4369
4370ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004371ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004372ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004373
4374ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004375ACCESSORS(GlobalObject, native_context, Context, kNativeContextOffset)
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00004376ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004377ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004378
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004379ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004380
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004381ACCESSORS(AccessorInfo, name, Object, kNameOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004382ACCESSORS_TO_SMI(AccessorInfo, flag, kFlagOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004383ACCESSORS(AccessorInfo, expected_receiver_type, Object,
4384 kExpectedReceiverTypeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004385
ulan@chromium.org750145a2013-03-07 15:14:13 +00004386ACCESSORS(DeclaredAccessorDescriptor, serialized_data, ByteArray,
4387 kSerializedDataOffset)
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00004388
4389ACCESSORS(DeclaredAccessorInfo, descriptor, DeclaredAccessorDescriptor,
4390 kDescriptorOffset)
4391
4392ACCESSORS(ExecutableAccessorInfo, getter, Object, kGetterOffset)
4393ACCESSORS(ExecutableAccessorInfo, setter, Object, kSetterOffset)
4394ACCESSORS(ExecutableAccessorInfo, data, Object, kDataOffset)
4395
danno@chromium.org1fd77d52013-06-07 16:01:45 +00004396ACCESSORS(Box, value, Object, kValueOffset)
4397
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004398ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
4399ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
4400
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004401ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
4402ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
4403ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
4404
4405ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
4406ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
4407ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
4408ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
4409ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
4410ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
4411
4412ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
4413ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
4414
4415ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
4416ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
4417
4418ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
4419ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004420ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
4421 kPropertyAccessorsOffset)
4422ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
4423 kPrototypeTemplateOffset)
4424ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
4425ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
4426 kNamedPropertyHandlerOffset)
4427ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
4428 kIndexedPropertyHandlerOffset)
4429ACCESSORS(FunctionTemplateInfo, instance_template, Object,
4430 kInstanceTemplateOffset)
4431ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
4432ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004433ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
4434 kInstanceCallHandlerOffset)
4435ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
4436 kAccessCheckInfoOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004437ACCESSORS_TO_SMI(FunctionTemplateInfo, flag, kFlagOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004438
4439ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00004440ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
4441 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004442
4443ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
4444ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
4445
4446ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
4447
jkummerow@chromium.org59297c72013-01-09 16:32:23 +00004448ACCESSORS(AllocationSiteInfo, payload, Object, kPayloadOffset)
4449
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004450ACCESSORS(Script, source, Object, kSourceOffset)
4451ACCESSORS(Script, name, Object, kNameOffset)
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00004452ACCESSORS(Script, id, Smi, kIdOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004453ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
4454ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00004455ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00004456ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004457ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004458ACCESSORS_TO_SMI(Script, type, kTypeOffset)
4459ACCESSORS_TO_SMI(Script, compilation_type, kCompilationTypeOffset)
4460ACCESSORS_TO_SMI(Script, compilation_state, kCompilationStateOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00004461ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00004462ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004463ACCESSORS_TO_SMI(Script, eval_from_instructions_offset,
4464 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004465
ager@chromium.org65dad4b2009-04-23 08:48:43 +00004466#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004467ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
4468ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
4469ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
4470ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
4471
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004472ACCESSORS_TO_SMI(BreakPointInfo, code_position, kCodePositionIndex)
4473ACCESSORS_TO_SMI(BreakPointInfo, source_position, kSourcePositionIndex)
4474ACCESSORS_TO_SMI(BreakPointInfo, statement_position, kStatementPositionIndex)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004475ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00004476#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004477
4478ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004479ACCESSORS(SharedFunctionInfo, optimized_code_map, Object,
4480 kOptimizedCodeMapOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004481ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
4482ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004483ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
4484 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004485ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004486ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
4487ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00004488ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004489SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004490
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00004491
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00004492SMI_ACCESSORS(FunctionTemplateInfo, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004493BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
4494 kHiddenPrototypeBit)
4495BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
4496BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
4497 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00004498BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
4499 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004500BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
4501 kIsExpressionBit)
4502BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
4503 kIsTopLevelBit)
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00004504
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004505BOOL_ACCESSORS(SharedFunctionInfo,
4506 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00004507 allows_lazy_compilation,
4508 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00004509BOOL_ACCESSORS(SharedFunctionInfo,
4510 compiler_hints,
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004511 allows_lazy_compilation_without_context,
4512 kAllowLazyCompilationWithoutContext)
4513BOOL_ACCESSORS(SharedFunctionInfo,
4514 compiler_hints,
whesse@chromium.org7b260152011-06-20 15:33:18 +00004515 uses_arguments,
4516 kUsesArguments)
4517BOOL_ACCESSORS(SharedFunctionInfo,
4518 compiler_hints,
4519 has_duplicate_parameters,
4520 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004521
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004522
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004523#if V8_HOST_ARCH_32_BIT
4524SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
4525SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004526 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004527SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004528 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004529SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
4530SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004531 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004532SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
4533SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004534 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004535SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00004536 kCompilerHintsOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004537SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004538SMI_ACCESSORS(SharedFunctionInfo, counters, kCountersOffset)
4539SMI_ACCESSORS(SharedFunctionInfo,
4540 stress_deopt_counter,
4541 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004542#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004543
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004544#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004545 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004546 int holder::name() { \
4547 int value = READ_INT_FIELD(this, offset); \
4548 ASSERT(kHeapObjectTag == 1); \
4549 ASSERT((value & kHeapObjectTag) == 0); \
4550 return value >> 1; \
4551 } \
4552 void holder::set_##name(int value) { \
4553 ASSERT(kHeapObjectTag == 1); \
4554 ASSERT((value & 0xC0000000) == 0xC0000000 || \
4555 (value & 0xC0000000) == 0x000000000); \
4556 WRITE_INT_FIELD(this, \
4557 offset, \
4558 (value << 1) & ~kHeapObjectTag); \
4559 }
4560
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004561#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
4562 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004563 INT_ACCESSORS(holder, name, offset)
4564
4565
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004566PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004567PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4568 formal_parameter_count,
4569 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004570
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004571PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
4572 expected_nof_properties,
4573 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004574PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
4575
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004576PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
4577PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4578 start_position_and_type,
4579 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004580
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00004581PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
4582 function_token_position,
4583 kFunctionTokenPositionOffset)
4584PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
4585 compiler_hints,
4586 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004587
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +00004588PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00004589
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +00004590PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, counters, kCountersOffset)
4591PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004592 stress_deopt_counter,
4593 kStressDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004594#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004595
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00004596
4597int SharedFunctionInfo::construction_count() {
4598 return READ_BYTE_FIELD(this, kConstructionCountOffset);
4599}
4600
4601
4602void SharedFunctionInfo::set_construction_count(int value) {
4603 ASSERT(0 <= value && value < 256);
4604 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
4605}
4606
4607
whesse@chromium.org7b260152011-06-20 15:33:18 +00004608BOOL_ACCESSORS(SharedFunctionInfo,
4609 compiler_hints,
4610 live_objects_may_exist,
4611 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00004612
4613
4614bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00004615 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00004616}
4617
4618
whesse@chromium.org7b260152011-06-20 15:33:18 +00004619BOOL_GETTER(SharedFunctionInfo,
4620 compiler_hints,
4621 optimization_disabled,
4622 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004623
4624
4625void SharedFunctionInfo::set_optimization_disabled(bool disable) {
4626 set_compiler_hints(BooleanBit::set(compiler_hints(),
4627 kOptimizationDisabled,
4628 disable));
4629 // If disabling optimizations we reflect that in the code object so
4630 // it will not be counted as optimizable code.
4631 if ((code()->kind() == Code::FUNCTION) && disable) {
4632 code()->set_optimizable(false);
4633 }
4634}
4635
4636
jkummerow@chromium.org212d9642012-05-11 15:02:09 +00004637int SharedFunctionInfo::profiler_ticks() {
4638 if (code()->kind() != Code::FUNCTION) return 0;
4639 return code()->profiler_ticks();
4640}
4641
4642
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004643LanguageMode SharedFunctionInfo::language_mode() {
4644 int hints = compiler_hints();
4645 if (BooleanBit::get(hints, kExtendedModeFunction)) {
4646 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
4647 return EXTENDED_MODE;
4648 }
4649 return BooleanBit::get(hints, kStrictModeFunction)
4650 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004651}
4652
4653
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004654void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
4655 // We only allow language mode transitions that go set the same language mode
4656 // again or go up in the chain:
4657 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
4658 ASSERT(this->language_mode() == CLASSIC_MODE ||
4659 this->language_mode() == language_mode ||
4660 language_mode == EXTENDED_MODE);
4661 int hints = compiler_hints();
4662 hints = BooleanBit::set(
4663 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
4664 hints = BooleanBit::set(
4665 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
4666 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004667}
4668
4669
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004670bool SharedFunctionInfo::is_classic_mode() {
4671 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
4672}
4673
4674BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
4675 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004676BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
4677BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
4678 name_should_print_as_anonymous,
4679 kNameShouldPrintAsAnonymous)
4680BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
4681BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00004682BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
4683BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
4684 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00004685BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00004686BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_cache, kDontCache)
ulan@chromium.org906e2fb2013-05-14 08:14:38 +00004687BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_flush, kDontFlush)
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00004688BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_generator, kIsGenerator)
whesse@chromium.org7b260152011-06-20 15:33:18 +00004689
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004690void SharedFunctionInfo::BeforeVisitingPointers() {
4691 if (IsInobjectSlackTrackingInProgress()) DetachInitialMap();
mstarzinger@chromium.org0ae265a2012-12-11 17:41:11 +00004692}
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00004693
mstarzinger@chromium.org0ae265a2012-12-11 17:41:11 +00004694
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00004695ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
4696ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
4697
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00004698ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
4699
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00004700bool Script::HasValidSource() {
4701 Object* src = this->source();
4702 if (!src->IsString()) return true;
4703 String* src_str = String::cast(src);
4704 if (!StringShape(src_str).IsExternal()) return true;
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00004705 if (src_str->IsOneByteRepresentation()) {
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00004706 return ExternalAsciiString::cast(src)->resource() != NULL;
4707 } else if (src_str->IsTwoByteRepresentation()) {
4708 return ExternalTwoByteString::cast(src)->resource() != NULL;
4709 }
4710 return true;
4711}
4712
4713
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00004714void SharedFunctionInfo::DontAdaptArguments() {
4715 ASSERT(code()->kind() == Code::BUILTIN);
4716 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
4717}
4718
4719
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004720int SharedFunctionInfo::start_position() {
4721 return start_position_and_type() >> kStartPositionShift;
4722}
4723
4724
4725void SharedFunctionInfo::set_start_position(int start_position) {
4726 set_start_position_and_type((start_position << kStartPositionShift)
4727 | (start_position_and_type() & ~kStartPositionMask));
4728}
4729
4730
4731Code* SharedFunctionInfo::code() {
4732 return Code::cast(READ_FIELD(this, kCodeOffset));
4733}
4734
4735
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004736void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004737 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004738 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004739}
4740
4741
yangguo@chromium.org9768bf12013-01-11 14:51:07 +00004742void SharedFunctionInfo::ReplaceCode(Code* value) {
4743 // If the GC metadata field is already used then the function was
4744 // enqueued as a code flushing candidate and we remove it now.
4745 if (code()->gc_metadata() != NULL) {
4746 CodeFlusher* flusher = GetHeap()->mark_compact_collector()->code_flusher();
4747 flusher->EvictCandidate(this);
4748 }
4749
4750 ASSERT(code()->gc_metadata() == NULL && value->gc_metadata() == NULL);
4751 set_code(value);
4752}
4753
4754
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004755ScopeInfo* SharedFunctionInfo::scope_info() {
4756 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00004757}
4758
4759
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004760void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00004761 WriteBarrierMode mode) {
4762 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004763 CONDITIONAL_WRITE_BARRIER(GetHeap(),
4764 this,
4765 kScopeInfoOffset,
4766 reinterpret_cast<Object*>(value),
4767 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00004768}
4769
4770
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004771bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004772 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004773 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004774}
4775
4776
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004777bool SharedFunctionInfo::IsApiFunction() {
4778 return function_data()->IsFunctionTemplateInfo();
4779}
4780
4781
4782FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
4783 ASSERT(IsApiFunction());
4784 return FunctionTemplateInfo::cast(function_data());
4785}
4786
4787
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004788bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00004789 return function_data()->IsSmi();
4790}
4791
4792
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004793BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
4794 ASSERT(HasBuiltinFunctionId());
4795 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00004796}
4797
4798
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004799int SharedFunctionInfo::ic_age() {
4800 return ICAgeBits::decode(counters());
4801}
4802
4803
4804void SharedFunctionInfo::set_ic_age(int ic_age) {
4805 set_counters(ICAgeBits::update(counters(), ic_age));
4806}
4807
4808
4809int SharedFunctionInfo::deopt_count() {
4810 return DeoptCountBits::decode(counters());
4811}
4812
4813
4814void SharedFunctionInfo::set_deopt_count(int deopt_count) {
4815 set_counters(DeoptCountBits::update(counters(), deopt_count));
4816}
4817
4818
4819void SharedFunctionInfo::increment_deopt_count() {
4820 int value = counters();
4821 int deopt_count = DeoptCountBits::decode(value);
4822 deopt_count = (deopt_count + 1) & DeoptCountBits::kMax;
4823 set_counters(DeoptCountBits::update(value, deopt_count));
4824}
4825
4826
4827int SharedFunctionInfo::opt_reenable_tries() {
4828 return OptReenableTriesBits::decode(counters());
4829}
4830
4831
4832void SharedFunctionInfo::set_opt_reenable_tries(int tries) {
4833 set_counters(OptReenableTriesBits::update(counters(), tries));
4834}
4835
4836
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004837bool SharedFunctionInfo::has_deoptimization_support() {
4838 Code* code = this->code();
4839 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
4840}
4841
4842
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004843void SharedFunctionInfo::TryReenableOptimization() {
4844 int tries = opt_reenable_tries();
4845 set_opt_reenable_tries((tries + 1) & OptReenableTriesBits::kMax);
4846 // We reenable optimization whenever the number of tries is a large
4847 // enough power of 2.
4848 if (tries >= 16 && (((tries - 1) & tries) == 0)) {
4849 set_optimization_disabled(false);
4850 set_opt_count(0);
4851 set_deopt_count(0);
4852 code()->set_optimizable(true);
4853 }
4854}
4855
4856
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004857bool JSFunction::IsBuiltin() {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004858 return context()->global_object()->IsJSBuiltinsObject();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004859}
4860
4861
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004862bool JSFunction::NeedsArgumentsAdaption() {
4863 return shared()->formal_parameter_count() !=
4864 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
4865}
4866
4867
4868bool JSFunction::IsOptimized() {
4869 return code()->kind() == Code::OPTIMIZED_FUNCTION;
4870}
4871
4872
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00004873bool JSFunction::IsOptimizable() {
4874 return code()->kind() == Code::FUNCTION && code()->optimizable();
4875}
4876
4877
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004878bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004879 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004880}
4881
4882
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00004883bool JSFunction::IsMarkedForInstallingRecompiledCode() {
4884 return code() == GetIsolate()->builtins()->builtin(
4885 Builtins::kInstallRecompiledCode);
4886}
4887
4888
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004889bool JSFunction::IsMarkedForParallelRecompilation() {
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00004890 return code() == GetIsolate()->builtins()->builtin(
4891 Builtins::kParallelRecompile);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004892}
4893
4894
4895bool JSFunction::IsInRecompileQueue() {
4896 return code() == GetIsolate()->builtins()->builtin(
4897 Builtins::kInRecompileQueue);
4898}
4899
4900
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004901Code* JSFunction::code() {
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00004902 return Code::cast(
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004903 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004904}
4905
4906
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004907void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004908 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00004909 Address entry = value->entry();
4910 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004911 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
4912 this,
4913 HeapObject::RawField(this, kCodeEntryOffset),
4914 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004915}
4916
4917
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00004918void JSFunction::set_code_no_write_barrier(Code* value) {
4919 ASSERT(!HEAP->InNewSpace(value));
4920 Address entry = value->entry();
4921 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
4922}
4923
4924
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004925void JSFunction::ReplaceCode(Code* code) {
4926 bool was_optimized = IsOptimized();
4927 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
4928
4929 set_code(code);
4930
4931 // Add/remove the function from the list of optimized functions for this
4932 // context based on the state change.
4933 if (!was_optimized && is_optimized) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004934 context()->native_context()->AddOptimizedFunction(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004935 }
4936 if (was_optimized && !is_optimized) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00004937 context()->native_context()->RemoveOptimizedFunction(this);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004938 }
4939}
4940
4941
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004942Context* JSFunction::context() {
4943 return Context::cast(READ_FIELD(this, kContextOffset));
4944}
4945
4946
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004947void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004948 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004949 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004950 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004951}
4952
4953ACCESSORS(JSFunction, prototype_or_initial_map, Object,
4954 kPrototypeOrInitialMapOffset)
4955
4956
4957Map* JSFunction::initial_map() {
4958 return Map::cast(prototype_or_initial_map());
4959}
4960
4961
4962void JSFunction::set_initial_map(Map* value) {
4963 set_prototype_or_initial_map(value);
4964}
4965
4966
4967bool JSFunction::has_initial_map() {
4968 return prototype_or_initial_map()->IsMap();
4969}
4970
4971
4972bool JSFunction::has_instance_prototype() {
4973 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
4974}
4975
4976
4977bool JSFunction::has_prototype() {
4978 return map()->has_non_instance_prototype() || has_instance_prototype();
4979}
4980
4981
4982Object* JSFunction::instance_prototype() {
4983 ASSERT(has_instance_prototype());
4984 if (has_initial_map()) return initial_map()->prototype();
4985 // When there is no initial map and the prototype is a JSObject, the
4986 // initial map field is used for the prototype field.
4987 return prototype_or_initial_map();
4988}
4989
4990
4991Object* JSFunction::prototype() {
4992 ASSERT(has_prototype());
4993 // If the function's prototype property has been set to a non-JSObject
4994 // value, that value is stored in the constructor field of the map.
4995 if (map()->has_non_instance_prototype()) return map()->constructor();
4996 return instance_prototype();
4997}
4998
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004999
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00005000bool JSFunction::should_have_prototype() {
5001 return map()->function_with_prototype();
5002}
5003
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005004
5005bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005006 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005007}
5008
5009
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005010FixedArray* JSFunction::literals() {
5011 ASSERT(!shared()->bound());
5012 return literals_or_bindings();
5013}
5014
5015
5016void JSFunction::set_literals(FixedArray* literals) {
5017 ASSERT(!shared()->bound());
5018 set_literals_or_bindings(literals);
5019}
5020
5021
5022FixedArray* JSFunction::function_bindings() {
5023 ASSERT(shared()->bound());
5024 return literals_or_bindings();
5025}
5026
5027
5028void JSFunction::set_function_bindings(FixedArray* bindings) {
5029 ASSERT(shared()->bound());
5030 // Bound function literal may be initialized to the empty fixed array
5031 // before the bindings are set.
5032 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
5033 bindings->map() == GetHeap()->fixed_cow_array_map());
5034 set_literals_or_bindings(bindings);
5035}
5036
5037
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00005038int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005039 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00005040 return literals()->length();
5041}
5042
5043
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005044Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00005045 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00005046 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005047}
5048
5049
5050void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
5051 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00005052 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00005053 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005054 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00005055}
5056
5057
5058Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00005059 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00005060 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
5061}
5062
5063
5064void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
5065 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00005066 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00005067 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005068 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005069}
5070
5071
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00005072ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005073ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00005074ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
5075ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
5076
5077
5078void JSProxy::InitializeBody(int object_size, Object* value) {
5079 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
5080 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
5081 WRITE_FIELD(this, offset, value);
5082 }
5083}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00005084
5085
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005086ACCESSORS(JSSet, table, Object, kTableOffset)
5087ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005088ACCESSORS(JSWeakMap, table, Object, kTableOffset)
5089ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00005090
5091
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005092Address Foreign::foreign_address() {
5093 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005094}
5095
5096
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00005097void Foreign::set_foreign_address(Address value) {
5098 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005099}
5100
5101
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005102ACCESSORS(JSGeneratorObject, function, JSFunction, kFunctionOffset)
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00005103ACCESSORS(JSGeneratorObject, context, Context, kContextOffset)
danno@chromium.orgca29dd82013-04-26 11:59:48 +00005104ACCESSORS(JSGeneratorObject, receiver, Object, kReceiverOffset)
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005105SMI_ACCESSORS(JSGeneratorObject, continuation, kContinuationOffset)
5106ACCESSORS(JSGeneratorObject, operand_stack, FixedArray, kOperandStackOffset)
ulan@chromium.org57ff8812013-05-10 08:16:55 +00005107SMI_ACCESSORS(JSGeneratorObject, stack_handler_index, kStackHandlerIndexOffset)
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005108
5109
5110JSGeneratorObject* JSGeneratorObject::cast(Object* obj) {
5111 ASSERT(obj->IsJSGeneratorObject());
5112 ASSERT(HeapObject::cast(obj)->Size() == JSGeneratorObject::kSize);
5113 return reinterpret_cast<JSGeneratorObject*>(obj);
5114}
5115
5116
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00005117ACCESSORS(JSModule, context, Object, kContextOffset)
danno@chromium.org81cac2b2012-07-10 11:28:27 +00005118ACCESSORS(JSModule, scope_info, ScopeInfo, kScopeInfoOffset)
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00005119
5120
5121JSModule* JSModule::cast(Object* obj) {
5122 ASSERT(obj->IsJSModule());
5123 ASSERT(HeapObject::cast(obj)->Size() == JSModule::kSize);
5124 return reinterpret_cast<JSModule*>(obj);
5125}
5126
5127
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005128ACCESSORS(JSValue, value, Object, kValueOffset)
5129
5130
5131JSValue* JSValue::cast(Object* obj) {
5132 ASSERT(obj->IsJSValue());
5133 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
5134 return reinterpret_cast<JSValue*>(obj);
5135}
5136
5137
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00005138ACCESSORS(JSDate, value, Object, kValueOffset)
5139ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
5140ACCESSORS(JSDate, year, Object, kYearOffset)
5141ACCESSORS(JSDate, month, Object, kMonthOffset)
5142ACCESSORS(JSDate, day, Object, kDayOffset)
5143ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
5144ACCESSORS(JSDate, hour, Object, kHourOffset)
5145ACCESSORS(JSDate, min, Object, kMinOffset)
5146ACCESSORS(JSDate, sec, Object, kSecOffset)
5147
5148
5149JSDate* JSDate::cast(Object* obj) {
5150 ASSERT(obj->IsJSDate());
5151 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
5152 return reinterpret_cast<JSDate*>(obj);
5153}
5154
5155
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00005156ACCESSORS(JSMessageObject, type, String, kTypeOffset)
5157ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
5158ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
5159ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
5160ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
5161SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
5162SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
5163
5164
5165JSMessageObject* JSMessageObject::cast(Object* obj) {
5166 ASSERT(obj->IsJSMessageObject());
5167 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
5168 return reinterpret_cast<JSMessageObject*>(obj);
5169}
5170
5171
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005172INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +00005173INT_ACCESSORS(Code, prologue_offset, kPrologueOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00005174ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00005175ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005176ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005177
5178
5179// Type feedback slot: type_feedback_info for FUNCTIONs, stub_info for STUBs.
5180void Code::InitializeTypeFeedbackInfoNoWriteBarrier(Object* value) {
5181 WRITE_FIELD(this, kTypeFeedbackInfoOffset, value);
5182}
5183
5184
5185Object* Code::type_feedback_info() {
5186 ASSERT(kind() == FUNCTION);
5187 return Object::cast(READ_FIELD(this, kTypeFeedbackInfoOffset));
5188}
5189
5190
5191void Code::set_type_feedback_info(Object* value, WriteBarrierMode mode) {
5192 ASSERT(kind() == FUNCTION);
5193 WRITE_FIELD(this, kTypeFeedbackInfoOffset, value);
5194 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kTypeFeedbackInfoOffset,
5195 value, mode);
5196}
5197
5198
5199int Code::stub_info() {
danno@chromium.orgca29dd82013-04-26 11:59:48 +00005200 ASSERT(kind() == COMPARE_IC || kind() == COMPARE_NIL_IC ||
5201 kind() == BINARY_OP_IC || kind() == LOAD_IC);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005202 Object* value = READ_FIELD(this, kTypeFeedbackInfoOffset);
5203 return Smi::cast(value)->value();
5204}
5205
5206
5207void Code::set_stub_info(int value) {
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00005208 ASSERT(kind() == COMPARE_IC ||
danno@chromium.orgca29dd82013-04-26 11:59:48 +00005209 kind() == COMPARE_NIL_IC ||
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00005210 kind() == BINARY_OP_IC ||
ulan@chromium.org750145a2013-03-07 15:14:13 +00005211 kind() == STUB ||
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00005212 kind() == LOAD_IC ||
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +00005213 kind() == KEYED_LOAD_IC ||
5214 kind() == STORE_IC ||
5215 kind() == KEYED_STORE_IC);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005216 WRITE_FIELD(this, kTypeFeedbackInfoOffset, Smi::FromInt(value));
5217}
5218
5219
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005220void Code::set_deoptimizing_functions(Object* value) {
5221 ASSERT(kind() == OPTIMIZED_FUNCTION);
5222 WRITE_FIELD(this, kTypeFeedbackInfoOffset, value);
5223}
5224
5225
5226Object* Code::deoptimizing_functions() {
5227 ASSERT(kind() == OPTIMIZED_FUNCTION);
5228 return Object::cast(READ_FIELD(this, kTypeFeedbackInfoOffset));
5229}
5230
5231
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00005232ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
danno@chromium.org88aa0582012-03-23 15:11:57 +00005233INT_ACCESSORS(Code, ic_age, kICAgeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005234
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005235
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005236byte* Code::instruction_start() {
5237 return FIELD_ADDR(this, kHeaderSize);
5238}
5239
5240
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00005241byte* Code::instruction_end() {
5242 return instruction_start() + instruction_size();
5243}
5244
5245
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005246int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00005247 return RoundUp(instruction_size(), kObjectAlignment);
5248}
5249
5250
5251ByteArray* Code::unchecked_relocation_info() {
5252 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005253}
5254
5255
5256byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00005257 return unchecked_relocation_info()->GetDataStartAddress();
5258}
5259
5260
5261int Code::relocation_size() {
5262 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005263}
5264
5265
5266byte* Code::entry() {
5267 return instruction_start();
5268}
5269
5270
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005271bool Code::contains(byte* inner_pointer) {
5272 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005273}
5274
5275
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005276ACCESSORS(JSArray, length, Object, kLengthOffset)
5277
5278
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00005279void* JSArrayBuffer::backing_store() {
5280 intptr_t ptr = READ_INTPTR_FIELD(this, kBackingStoreOffset);
5281 return reinterpret_cast<void*>(ptr);
5282}
5283
5284
5285void JSArrayBuffer::set_backing_store(void* value, WriteBarrierMode mode) {
5286 intptr_t ptr = reinterpret_cast<intptr_t>(value);
5287 WRITE_INTPTR_FIELD(this, kBackingStoreOffset, ptr);
5288}
5289
5290
5291ACCESSORS(JSArrayBuffer, byte_length, Object, kByteLengthOffset)
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +00005292ACCESSORS_TO_SMI(JSArrayBuffer, flag, kFlagOffset)
5293
5294
5295bool JSArrayBuffer::is_external() {
5296 return BooleanBit::get(flag(), kIsExternalBit);
5297}
5298
5299
5300void JSArrayBuffer::set_is_external(bool value) {
5301 set_flag(BooleanBit::set(flag(), kIsExternalBit, value));
5302}
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00005303
5304
danno@chromium.org1fd77d52013-06-07 16:01:45 +00005305ACCESSORS(JSArrayBuffer, weak_next, Object, kWeakNextOffset)
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005306ACCESSORS(JSArrayBuffer, weak_first_view, Object, kWeakFirstViewOffset)
danno@chromium.org1fd77d52013-06-07 16:01:45 +00005307
5308
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00005309ACCESSORS(JSArrayBufferView, buffer, Object, kBufferOffset)
5310ACCESSORS(JSArrayBufferView, byte_offset, Object, kByteOffsetOffset)
5311ACCESSORS(JSArrayBufferView, byte_length, Object, kByteLengthOffset)
5312ACCESSORS(JSArrayBufferView, weak_next, Object, kWeakNextOffset)
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005313ACCESSORS(JSTypedArray, length, Object, kLengthOffset)
5314
ager@chromium.org236ad962008-09-25 09:45:57 +00005315ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00005316
5317
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00005318JSRegExp::Type JSRegExp::TypeTag() {
5319 Object* data = this->data();
5320 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
5321 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
5322 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00005323}
5324
5325
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00005326int JSRegExp::CaptureCount() {
5327 switch (TypeTag()) {
5328 case ATOM:
5329 return 0;
5330 case IRREGEXP:
5331 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
5332 default:
5333 UNREACHABLE();
5334 return -1;
5335 }
5336}
5337
5338
ager@chromium.orga74f0da2008-12-03 16:05:52 +00005339JSRegExp::Flags JSRegExp::GetFlags() {
5340 ASSERT(this->data()->IsFixedArray());
5341 Object* data = this->data();
5342 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
5343 return Flags(smi->value());
5344}
5345
5346
5347String* JSRegExp::Pattern() {
5348 ASSERT(this->data()->IsFixedArray());
5349 Object* data = this->data();
5350 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
5351 return pattern;
5352}
5353
5354
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00005355Object* JSRegExp::DataAt(int index) {
5356 ASSERT(TypeTag() != NOT_COMPILED);
5357 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00005358}
5359
5360
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00005361void JSRegExp::SetDataAt(int index, Object* value) {
5362 ASSERT(TypeTag() != NOT_COMPILED);
5363 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
5364 FixedArray::cast(data())->set(index, value);
5365}
5366
5367
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00005368ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00005369 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005370#if DEBUG
5371 FixedArrayBase* fixed_array =
5372 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
5373 Map* map = fixed_array->map();
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005374 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
5375 (map == GetHeap()->fixed_array_map() ||
5376 map == GetHeap()->fixed_cow_array_map())) ||
5377 (IsFastDoubleElementsKind(kind) &&
5378 (fixed_array->IsFixedDoubleArray() ||
5379 fixed_array == GetHeap()->empty_fixed_array())) ||
5380 (kind == DICTIONARY_ELEMENTS &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005381 fixed_array->IsFixedArray() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005382 fixed_array->IsDictionary()) ||
5383 (kind > DICTIONARY_ELEMENTS));
5384 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
5385 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005386#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00005387 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005388}
5389
5390
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00005391ElementsAccessor* JSObject::GetElementsAccessor() {
5392 return ElementsAccessor::ForKind(GetElementsKind());
5393}
5394
5395
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005396bool JSObject::HasFastObjectElements() {
5397 return IsFastObjectElementsKind(GetElementsKind());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005398}
5399
5400
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005401bool JSObject::HasFastSmiElements() {
5402 return IsFastSmiElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005403}
5404
5405
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005406bool JSObject::HasFastSmiOrObjectElements() {
5407 return IsFastSmiOrObjectElementsKind(GetElementsKind());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005408}
5409
5410
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00005411bool JSObject::HasFastDoubleElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005412 return IsFastDoubleElementsKind(GetElementsKind());
5413}
5414
5415
5416bool JSObject::HasFastHoleyElements() {
5417 return IsFastHoleyElementsKind(GetElementsKind());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00005418}
5419
5420
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005421bool JSObject::HasFastElements() {
5422 return IsFastElementsKind(GetElementsKind());
5423}
5424
5425
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005426bool JSObject::HasDictionaryElements() {
5427 return GetElementsKind() == DICTIONARY_ELEMENTS;
5428}
5429
5430
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005431bool JSObject::HasNonStrictArgumentsElements() {
5432 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
5433}
5434
5435
ager@chromium.org3811b432009-10-28 14:53:37 +00005436bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005437 HeapObject* array = elements();
5438 ASSERT(array != NULL);
5439 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00005440}
5441
5442
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005443#define EXTERNAL_ELEMENTS_CHECK(name, type) \
5444bool JSObject::HasExternal##name##Elements() { \
5445 HeapObject* array = elements(); \
5446 ASSERT(array != NULL); \
5447 if (!array->IsHeapObject()) \
5448 return false; \
5449 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00005450}
5451
5452
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005453EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
5454EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
5455EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
5456EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
5457 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
5458EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
5459EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
5460 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
5461EXTERNAL_ELEMENTS_CHECK(Float,
5462 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00005463EXTERNAL_ELEMENTS_CHECK(Double,
5464 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00005465EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00005466
5467
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005468bool JSObject::HasNamedInterceptor() {
5469 return map()->has_named_interceptor();
5470}
5471
5472
5473bool JSObject::HasIndexedInterceptor() {
5474 return map()->has_indexed_interceptor();
5475}
5476
5477
lrn@chromium.org303ada72010-10-27 09:33:13 +00005478MaybeObject* JSObject::EnsureWritableFastElements() {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005479 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00005480 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005481 Isolate* isolate = GetIsolate();
5482 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00005483 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005484 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
5485 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00005486 if (!maybe_writable_elems->ToObject(&writable_elems)) {
5487 return maybe_writable_elems;
5488 }
5489 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00005490 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005491 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00005492 return writable_elems;
5493}
5494
5495
ulan@chromium.org750145a2013-03-07 15:14:13 +00005496NameDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005497 ASSERT(!HasFastProperties());
ulan@chromium.org750145a2013-03-07 15:14:13 +00005498 return NameDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005499}
5500
5501
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005502SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00005503 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005504 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005505}
5506
5507
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005508bool Name::IsHashFieldComputed(uint32_t field) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005509 return (field & kHashNotComputedMask) == 0;
5510}
5511
5512
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005513bool Name::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005514 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005515}
5516
5517
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005518uint32_t Name::Hash() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005519 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00005520 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005521 if (IsHashFieldComputed(field)) return field >> kHashShift;
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005522 // Slow case: compute hash code and set it. Has to be a string.
5523 return String::cast(this)->ComputeAndSetHash();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005524}
5525
5526
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005527StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00005528 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005529 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00005530 array_index_(0),
5531 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005532 is_first_char_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005533 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005534}
ager@chromium.org7c537e22008-10-16 08:43:32 +00005535
5536
5537bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00005538 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005539}
5540
5541
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005542uint32_t StringHasher::AddCharacterCore(uint32_t running_hash, uint16_t c) {
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005543 running_hash += c;
5544 running_hash += (running_hash << 10);
5545 running_hash ^= (running_hash >> 6);
5546 return running_hash;
5547}
5548
5549
5550uint32_t StringHasher::GetHashCore(uint32_t running_hash) {
5551 running_hash += (running_hash << 3);
5552 running_hash ^= (running_hash >> 11);
5553 running_hash += (running_hash << 15);
5554 if ((running_hash & String::kHashBitMask) == 0) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00005555 return kZeroHash;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005556 }
5557 return running_hash;
5558}
5559
5560
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005561void StringHasher::AddCharacter(uint16_t c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005562 // Use the Jenkins one-at-a-time hash function to update the hash
5563 // for the given character.
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00005564 raw_running_hash_ = AddCharacterCore(raw_running_hash_, c);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005565}
5566
5567
5568bool StringHasher::UpdateIndex(uint16_t c) {
5569 ASSERT(is_array_index_);
5570 if (c < '0' || c > '9') {
5571 is_array_index_ = false;
5572 return false;
5573 }
5574 int d = c - '0';
5575 if (is_first_char_) {
5576 is_first_char_ = false;
5577 if (c == '0' && length_ > 1) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00005578 is_array_index_ = false;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005579 return false;
5580 }
5581 }
5582 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
5583 is_array_index_ = false;
5584 return false;
5585 }
5586 array_index_ = array_index_ * 10 + d;
5587 return true;
5588}
5589
5590
5591template<typename Char>
5592inline void StringHasher::AddCharacters(const Char* chars, int length) {
5593 ASSERT(sizeof(Char) == 1 || sizeof(Char) == 2);
5594 int i = 0;
5595 if (is_array_index_) {
5596 for (; i < length; i++) {
5597 AddCharacter(chars[i]);
5598 if (!UpdateIndex(chars[i])) {
5599 i++;
5600 break;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005601 }
5602 }
5603 }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005604 for (; i < length; i++) {
5605 ASSERT(!is_array_index_);
5606 AddCharacter(chars[i]);
yangguo@chromium.org154ff992012-03-13 08:09:54 +00005607 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00005608}
5609
5610
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005611template <typename schar>
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005612uint32_t StringHasher::HashSequentialString(const schar* chars,
5613 int length,
5614 uint32_t seed) {
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00005615 StringHasher hasher(length, seed);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005616 if (!hasher.has_trivial_hash()) hasher.AddCharacters(chars, length);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005617 return hasher.GetHashField();
5618}
5619
5620
ulan@chromium.org750145a2013-03-07 15:14:13 +00005621bool Name::AsArrayIndex(uint32_t* index) {
5622 return IsString() && String::cast(this)->AsArrayIndex(index);
5623}
5624
5625
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005626bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00005627 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00005628 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
5629 return false;
5630 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005631 return SlowAsArrayIndex(index);
5632}
5633
5634
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00005635Object* JSReceiver::GetPrototype() {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00005636 return map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005637}
5638
5639
yangguo@chromium.orgc74d6742012-06-29 15:15:45 +00005640Object* JSReceiver::GetConstructor() {
5641 return map()->constructor();
5642}
5643
5644
ulan@chromium.org750145a2013-03-07 15:14:13 +00005645bool JSReceiver::HasProperty(Name* name) {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00005646 if (IsJSProxy()) {
5647 return JSProxy::cast(this)->HasPropertyWithHandler(name);
5648 }
5649 return GetPropertyAttribute(name) != ABSENT;
5650}
5651
5652
ulan@chromium.org750145a2013-03-07 15:14:13 +00005653bool JSReceiver::HasLocalProperty(Name* name) {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00005654 if (IsJSProxy()) {
5655 return JSProxy::cast(this)->HasPropertyWithHandler(name);
5656 }
5657 return GetLocalPropertyAttribute(name) != ABSENT;
5658}
5659
5660
ulan@chromium.org750145a2013-03-07 15:14:13 +00005661PropertyAttributes JSReceiver::GetPropertyAttribute(Name* key) {
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00005662 uint32_t index;
5663 if (IsJSObject() && key->AsArrayIndex(&index)) {
5664 return GetElementAttribute(index);
5665 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005666 return GetPropertyAttributeWithReceiver(this, key);
5667}
5668
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00005669
5670PropertyAttributes JSReceiver::GetElementAttribute(uint32_t index) {
5671 if (IsJSProxy()) {
5672 return JSProxy::cast(this)->GetElementAttributeWithHandler(this, index);
5673 }
5674 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5675 this, index, true);
5676}
5677
5678
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005679// TODO(504): this may be useful in other places too where JSGlobalProxy
5680// is used.
5681Object* JSObject::BypassGlobalProxy() {
5682 if (IsJSGlobalProxy()) {
5683 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005684 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005685 ASSERT(proto->IsJSGlobalObject());
5686 return proto;
5687 }
5688 return this;
5689}
5690
5691
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005692MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
5693 return IsJSProxy()
5694 ? JSProxy::cast(this)->GetIdentityHash(flag)
5695 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00005696}
5697
5698
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005699bool JSReceiver::HasElement(uint32_t index) {
5700 if (IsJSProxy()) {
5701 return JSProxy::cast(this)->HasElementWithHandler(index);
5702 }
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +00005703 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5704 this, index, true) != ABSENT;
5705}
5706
5707
5708bool JSReceiver::HasLocalElement(uint32_t index) {
5709 if (IsJSProxy()) {
5710 return JSProxy::cast(this)->HasElementWithHandler(index);
5711 }
5712 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5713 this, index, false) != ABSENT;
5714}
5715
5716
5717PropertyAttributes JSReceiver::GetLocalElementAttribute(uint32_t index) {
5718 if (IsJSProxy()) {
5719 return JSProxy::cast(this)->GetElementAttributeWithHandler(this, index);
5720 }
5721 return JSObject::cast(this)->GetElementAttributeWithReceiver(
5722 this, index, false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005723}
5724
5725
5726bool AccessorInfo::all_can_read() {
5727 return BooleanBit::get(flag(), kAllCanReadBit);
5728}
5729
5730
5731void AccessorInfo::set_all_can_read(bool value) {
5732 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
5733}
5734
5735
5736bool AccessorInfo::all_can_write() {
5737 return BooleanBit::get(flag(), kAllCanWriteBit);
5738}
5739
5740
5741void AccessorInfo::set_all_can_write(bool value) {
5742 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
5743}
5744
5745
ager@chromium.org870a0b62008-11-04 11:43:05 +00005746bool AccessorInfo::prohibits_overwriting() {
5747 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
5748}
5749
5750
5751void AccessorInfo::set_prohibits_overwriting(bool value) {
5752 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
5753}
5754
5755
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005756PropertyAttributes AccessorInfo::property_attributes() {
5757 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
5758}
5759
5760
5761void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00005762 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005763}
5764
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005765
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005766bool AccessorInfo::IsCompatibleReceiver(Object* receiver) {
5767 Object* function_template = expected_receiver_type();
5768 if (!function_template->IsFunctionTemplateInfo()) return true;
5769 return receiver->IsInstanceOf(FunctionTemplateInfo::cast(function_template));
5770}
5771
5772
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005773template<typename Shape, typename Key>
5774void Dictionary<Shape, Key>::SetEntry(int entry,
5775 Object* key,
5776 Object* value) {
5777 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
5778}
5779
5780
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005781template<typename Shape, typename Key>
5782void Dictionary<Shape, Key>::SetEntry(int entry,
5783 Object* key,
5784 Object* value,
5785 PropertyDetails details) {
ulan@chromium.org750145a2013-03-07 15:14:13 +00005786 ASSERT(!key->IsName() ||
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00005787 details.IsDeleted() ||
5788 details.dictionary_index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005789 int index = HashTable<Shape, Key>::EntryToIndex(entry);
rossberg@chromium.org79e79022013-06-03 15:43:46 +00005790 DisallowHeapAllocation no_gc;
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005791 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00005792 FixedArray::set(index, key, mode);
5793 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005794 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005795}
5796
5797
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005798bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
5799 ASSERT(other->IsNumber());
5800 return key == static_cast<uint32_t>(other->Number());
5801}
5802
5803
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005804uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
5805 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005806}
5807
5808
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005809uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
5810 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005811 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005812 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005813}
5814
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00005815uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
5816 return ComputeIntegerHash(key, seed);
5817}
5818
5819uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
5820 uint32_t seed,
5821 Object* other) {
5822 ASSERT(other->IsNumber());
5823 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
5824}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005825
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00005826MaybeObject* NumberDictionaryShape::AsObject(Heap* heap, uint32_t key) {
5827 return heap->NumberFromUint32(key);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005828}
5829
5830
ulan@chromium.org750145a2013-03-07 15:14:13 +00005831bool NameDictionaryShape::IsMatch(Name* key, Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005832 // We know that all entries in a hash table had their hash keys created.
5833 // Use that knowledge to have fast failure.
ulan@chromium.org750145a2013-03-07 15:14:13 +00005834 if (key->Hash() != Name::cast(other)->Hash()) return false;
5835 return key->Equals(Name::cast(other));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005836}
5837
5838
ulan@chromium.org750145a2013-03-07 15:14:13 +00005839uint32_t NameDictionaryShape::Hash(Name* key) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005840 return key->Hash();
5841}
5842
5843
ulan@chromium.org750145a2013-03-07 15:14:13 +00005844uint32_t NameDictionaryShape::HashForObject(Name* key, Object* other) {
5845 return Name::cast(other)->Hash();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005846}
5847
5848
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00005849MaybeObject* NameDictionaryShape::AsObject(Heap* heap, Name* key) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005850 return key;
5851}
5852
5853
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005854template <int entrysize>
5855bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
5856 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005857}
5858
5859
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005860template <int entrysize>
5861uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005862 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
5863 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005864}
5865
5866
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005867template <int entrysize>
5868uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
5869 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005870 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
5871 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005872}
5873
5874
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005875template <int entrysize>
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00005876MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Heap* heap,
5877 Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00005878 return key;
5879}
5880
5881
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005882void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005883 // No write barrier is needed since empty_fixed_array is not in new space.
5884 // Please note this function is used during marking:
5885 // - MarkCompactCollector::MarkUnmarkedObject
danno@chromium.org88aa0582012-03-23 15:11:57 +00005886 // - IncrementalMarking::Step
danno@chromium.org72204d52012-10-31 10:02:10 +00005887 ASSERT(!heap->InNewSpace(heap->empty_fixed_array()));
5888 WRITE_FIELD(this, kCodeCacheOffset, heap->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00005889}
5890
5891
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005892void JSArray::EnsureSize(int required_size) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005893 ASSERT(HasFastSmiOrObjectElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00005894 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005895 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
5896 if (elts->length() < required_size) {
5897 // Doubling in size would be overkill, but leave some slack to avoid
5898 // constantly growing.
5899 Expand(required_size + (required_size >> 3));
5900 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005901 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00005902 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
5903 // Expand will allocate a new backing store in new space even if the size
5904 // we asked for isn't larger than what we had before.
5905 Expand(required_size);
5906 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00005907}
5908
5909
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005910void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005911 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00005912 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
5913}
5914
5915
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005916bool JSArray::AllowsSetElementsLength() {
5917 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
5918 ASSERT(result == !HasExternalArrayElements());
5919 return result;
5920}
5921
5922
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005923MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
5924 MaybeObject* maybe_result = EnsureCanContainElements(
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005925 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005926 if (maybe_result->IsFailure()) return maybe_result;
5927 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005928 IsFastDoubleElementsKind(GetElementsKind())) ||
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005929 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005930 (IsFastObjectElementsKind(GetElementsKind()) ||
5931 (IsFastSmiElementsKind(GetElementsKind()) &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005932 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00005933 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005934 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005935 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00005936}
5937
5938
lrn@chromium.org303ada72010-10-27 09:33:13 +00005939MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00005940 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005941 return GetHeap()->CopyFixedArray(this);
5942}
5943
5944
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005945MaybeObject* FixedDoubleArray::Copy() {
5946 if (length() == 0) return this;
5947 return GetHeap()->CopyFixedDoubleArray(this);
5948}
5949
5950
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00005951void TypeFeedbackCells::SetAstId(int index, TypeFeedbackId id) {
5952 set(1 + index * 2, Smi::FromInt(id.ToInt()));
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005953}
5954
5955
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00005956TypeFeedbackId TypeFeedbackCells::AstId(int index) {
5957 return TypeFeedbackId(Smi::cast(get(1 + index * 2))->value());
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005958}
5959
5960
danno@chromium.org41728482013-06-12 22:31:22 +00005961void TypeFeedbackCells::SetCell(int index, Cell* cell) {
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005962 set(index * 2, cell);
5963}
5964
5965
danno@chromium.org41728482013-06-12 22:31:22 +00005966Cell* TypeFeedbackCells::GetCell(int index) {
5967 return Cell::cast(get(index * 2));
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005968}
5969
5970
5971Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
5972 return isolate->factory()->the_hole_value();
5973}
5974
5975
5976Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
5977 return isolate->factory()->undefined_value();
5978}
5979
5980
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00005981Handle<Object> TypeFeedbackCells::MonomorphicArraySentinel(Isolate* isolate,
5982 ElementsKind elements_kind) {
5983 return Handle<Object>(Smi::FromInt(static_cast<int>(elements_kind)), isolate);
5984}
5985
5986
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005987Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
danno@chromium.org72204d52012-10-31 10:02:10 +00005988 return heap->the_hole_value();
danno@chromium.orgfa458e42012-02-01 10:48:36 +00005989}
5990
5991
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00005992int TypeFeedbackInfo::ic_total_count() {
5993 int current = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
5994 return ICTotalCountField::decode(current);
5995}
5996
5997
5998void TypeFeedbackInfo::set_ic_total_count(int count) {
5999 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
6000 value = ICTotalCountField::update(value,
6001 ICTotalCountField::decode(count));
6002 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(value));
6003}
6004
6005
6006int TypeFeedbackInfo::ic_with_type_info_count() {
6007 int current = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
6008 return ICsWithTypeInfoCountField::decode(current);
6009}
6010
6011
6012void TypeFeedbackInfo::change_ic_with_type_info_count(int delta) {
6013 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
6014 int new_count = ICsWithTypeInfoCountField::decode(value) + delta;
6015 // We can get negative count here when the type-feedback info is
6016 // shared between two code objects. The can only happen when
6017 // the debugger made a shallow copy of code object (see Heap::CopyCode).
6018 // Since we do not optimize when the debugger is active, we can skip
6019 // this counter update.
6020 if (new_count >= 0) {
6021 new_count &= ICsWithTypeInfoCountField::kMask;
6022 value = ICsWithTypeInfoCountField::update(value, new_count);
6023 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(value));
6024 }
6025}
6026
6027
6028void TypeFeedbackInfo::initialize_storage() {
6029 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(0));
6030 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(0));
6031}
6032
6033
6034void TypeFeedbackInfo::change_own_type_change_checksum() {
6035 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
6036 int checksum = OwnTypeChangeChecksum::decode(value);
6037 checksum = (checksum + 1) % (1 << kTypeChangeChecksumBits);
6038 value = OwnTypeChangeChecksum::update(value, checksum);
6039 // Ensure packed bit field is in Smi range.
6040 if (value > Smi::kMaxValue) value |= Smi::kMinValue;
6041 if (value < Smi::kMinValue) value &= ~Smi::kMinValue;
6042 WRITE_FIELD(this, kStorage1Offset, Smi::FromInt(value));
6043}
6044
6045
6046void TypeFeedbackInfo::set_inlined_type_change_checksum(int checksum) {
6047 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
6048 int mask = (1 << kTypeChangeChecksumBits) - 1;
6049 value = InlinedTypeChangeChecksum::update(value, checksum & mask);
6050 // Ensure packed bit field is in Smi range.
6051 if (value > Smi::kMaxValue) value |= Smi::kMinValue;
6052 if (value < Smi::kMinValue) value &= ~Smi::kMinValue;
6053 WRITE_FIELD(this, kStorage2Offset, Smi::FromInt(value));
6054}
6055
6056
6057int TypeFeedbackInfo::own_type_change_checksum() {
6058 int value = Smi::cast(READ_FIELD(this, kStorage1Offset))->value();
6059 return OwnTypeChangeChecksum::decode(value);
6060}
6061
6062
6063bool TypeFeedbackInfo::matches_inlined_type_change_checksum(int checksum) {
6064 int value = Smi::cast(READ_FIELD(this, kStorage2Offset))->value();
6065 int mask = (1 << kTypeChangeChecksumBits) - 1;
6066 return InlinedTypeChangeChecksum::decode(value) == (checksum & mask);
6067}
6068
6069
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00006070ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
6071 kTypeFeedbackCellsOffset)
6072
6073
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00006074SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
6075
6076
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006077Relocatable::Relocatable(Isolate* isolate) {
6078 ASSERT(isolate == Isolate::Current());
6079 isolate_ = isolate;
6080 prev_ = isolate->relocatable_top();
6081 isolate->set_relocatable_top(this);
6082}
6083
6084
6085Relocatable::~Relocatable() {
6086 ASSERT(isolate_ == Isolate::Current());
6087 ASSERT_EQ(isolate_->relocatable_top(), this);
6088 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00006089}
6090
6091
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006092int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
6093 return map->instance_size();
6094}
6095
6096
ager@chromium.orgea91cc52011-05-23 06:06:11 +00006097void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006098 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00006099 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006100}
6101
6102
6103template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00006104void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006105 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00006106 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006107}
6108
6109
6110void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
6111 typedef v8::String::ExternalAsciiStringResource Resource;
6112 v->VisitExternalAsciiString(
6113 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
6114}
6115
6116
6117template<typename StaticVisitor>
6118void ExternalAsciiString::ExternalAsciiStringIterateBody() {
6119 typedef v8::String::ExternalAsciiStringResource Resource;
6120 StaticVisitor::VisitExternalAsciiString(
6121 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
6122}
6123
6124
6125void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
6126 typedef v8::String::ExternalStringResource Resource;
6127 v->VisitExternalTwoByteString(
6128 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
6129}
6130
6131
6132template<typename StaticVisitor>
6133void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
6134 typedef v8::String::ExternalStringResource Resource;
6135 StaticVisitor::VisitExternalTwoByteString(
6136 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
6137}
6138
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006139
6140template<int start_offset, int end_offset, int size>
6141void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
6142 HeapObject* obj,
6143 ObjectVisitor* v) {
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00006144 v->VisitPointers(HeapObject::RawField(obj, start_offset),
6145 HeapObject::RawField(obj, end_offset));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006146}
6147
6148
6149template<int start_offset>
6150void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
6151 int object_size,
6152 ObjectVisitor* v) {
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00006153 v->VisitPointers(HeapObject::RawField(obj, start_offset),
6154 HeapObject::RawField(obj, object_size));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006155}
6156
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00006157
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00006158#undef TYPE_CHECKER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006159#undef CAST_ACCESSOR
6160#undef INT_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006161#undef ACCESSORS
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00006162#undef ACCESSORS_TO_SMI
6163#undef SMI_ACCESSORS
6164#undef BOOL_GETTER
6165#undef BOOL_ACCESSORS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006166#undef FIELD_ADDR
6167#undef READ_FIELD
6168#undef WRITE_FIELD
6169#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00006170#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006171#undef READ_DOUBLE_FIELD
6172#undef WRITE_DOUBLE_FIELD
6173#undef READ_INT_FIELD
6174#undef WRITE_INT_FIELD
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00006175#undef READ_INTPTR_FIELD
6176#undef WRITE_INTPTR_FIELD
6177#undef READ_UINT32_FIELD
6178#undef WRITE_UINT32_FIELD
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00006179#undef READ_SHORT_FIELD
6180#undef WRITE_SHORT_FIELD
6181#undef READ_BYTE_FIELD
6182#undef WRITE_BYTE_FIELD
6183
6184
6185} } // namespace v8::internal
6186
6187#endif // V8_OBJECTS_INL_H_