blob: 503e8442af605804d3924253af33fc1a8df5b754 [file] [log] [blame]
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001// Copyright 2011 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27//
28// Review notes:
29//
ager@chromium.org32912102009-01-16 10:38:43 +000030// - The use of macros in these inline functions may seem superfluous
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000031// but it is absolutely needed to make sure gcc generates optimal
32// code. gcc is not happy when attempting to inline too deep.
33//
34
35#ifndef V8_OBJECTS_INL_H_
36#define V8_OBJECTS_INL_H_
37
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000038#include "objects.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000039#include "contexts.h"
40#include "conversions-inl.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000041#include "heap.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000042#include "isolate.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000043#include "property.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000044#include "spaces.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000045#include "v8memory.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000046
kasperl@chromium.org71affb52009-05-26 05:44:31 +000047namespace v8 {
48namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000049
50PropertyDetails::PropertyDetails(Smi* smi) {
51 value_ = smi->value();
52}
53
54
55Smi* PropertyDetails::AsSmi() {
56 return Smi::FromInt(value_);
57}
58
59
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000060PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000061 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000062 return PropertyDetails(smi);
63}
64
65
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000066#define CAST_ACCESSOR(type) \
67 type* type::cast(Object* object) { \
68 ASSERT(object->Is##type()); \
69 return reinterpret_cast<type*>(object); \
70 }
71
72
73#define INT_ACCESSORS(holder, name, offset) \
74 int holder::name() { return READ_INT_FIELD(this, offset); } \
75 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
76
77
78#define ACCESSORS(holder, name, type, offset) \
79 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000080 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000081 WRITE_FIELD(this, offset, value); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000082 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode); \
83 }
84
85
86// GC-safe accessors do not use HeapObject::GetHeap(), but access TLS instead.
87#define ACCESSORS_GCSAFE(holder, name, type, offset) \
88 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
89 void holder::set_##name(type* value, WriteBarrierMode mode) { \
90 WRITE_FIELD(this, offset, value); \
91 CONDITIONAL_WRITE_BARRIER(HEAP, this, offset, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000092 }
93
94
95#define SMI_ACCESSORS(holder, name, offset) \
96 int holder::name() { \
97 Object* value = READ_FIELD(this, offset); \
98 return Smi::cast(value)->value(); \
99 } \
100 void holder::set_##name(int value) { \
101 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
102 }
103
104
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000105#define BOOL_GETTER(holder, field, name, offset) \
106 bool holder::name() { \
107 return BooleanBit::get(field(), offset); \
108 } \
109
110
111#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000112 bool holder::name() { \
113 return BooleanBit::get(field(), offset); \
114 } \
115 void holder::set_##name(bool value) { \
116 set_##field(BooleanBit::set(field(), offset, value)); \
117 }
118
119
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000120bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
121 // There is a constraint on the object; check.
122 if (!this->IsJSObject()) return false;
123 // Fetch the constructor function of the object.
124 Object* cons_obj = JSObject::cast(this)->map()->constructor();
125 if (!cons_obj->IsJSFunction()) return false;
126 JSFunction* fun = JSFunction::cast(cons_obj);
127 // Iterate through the chain of inheriting function templates to
128 // see if the required one occurs.
129 for (Object* type = fun->shared()->function_data();
130 type->IsFunctionTemplateInfo();
131 type = FunctionTemplateInfo::cast(type)->parent_template()) {
132 if (type == expected) return true;
133 }
134 // Didn't find the required type in the inheritance chain.
135 return false;
136}
137
138
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000139bool Object::IsSmi() {
140 return HAS_SMI_TAG(this);
141}
142
143
144bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000145 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000146}
147
148
149bool Object::IsHeapNumber() {
150 return Object::IsHeapObject()
151 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
152}
153
154
155bool Object::IsString() {
156 return Object::IsHeapObject()
157 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
158}
159
160
ager@chromium.org870a0b62008-11-04 11:43:05 +0000161bool Object::IsSymbol() {
162 if (!this->IsHeapObject()) return false;
163 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000164 // Because the symbol tag is non-zero and no non-string types have the
165 // symbol bit set we can test for symbols with a very simple test
166 // operation.
167 ASSERT(kSymbolTag != 0);
168 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
169 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000170}
171
172
173bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000174 if (!this->IsHeapObject()) return false;
175 uint32_t type = HeapObject::cast(this)->map()->instance_type();
176 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
177 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000178}
179
180
ager@chromium.org870a0b62008-11-04 11:43:05 +0000181bool Object::IsSeqString() {
182 if (!IsString()) return false;
183 return StringShape(String::cast(this)).IsSequential();
184}
185
186
187bool Object::IsSeqAsciiString() {
188 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000189 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000190 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000191}
192
193
194bool Object::IsSeqTwoByteString() {
195 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000196 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000197 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000198}
199
200
201bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000202 if (!IsString()) return false;
203 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000204}
205
206
207bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000208 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000209 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000210 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000211}
212
213
214bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000215 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000216 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000217 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000218}
219
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000220bool Object::HasValidElements() {
221 // Dictionary is covered under FixedArray.
222 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
223}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000224
ager@chromium.org870a0b62008-11-04 11:43:05 +0000225StringShape::StringShape(String* str)
226 : type_(str->map()->instance_type()) {
227 set_valid();
228 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000229}
230
231
ager@chromium.org870a0b62008-11-04 11:43:05 +0000232StringShape::StringShape(Map* map)
233 : type_(map->instance_type()) {
234 set_valid();
235 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000236}
237
238
ager@chromium.org870a0b62008-11-04 11:43:05 +0000239StringShape::StringShape(InstanceType t)
240 : type_(static_cast<uint32_t>(t)) {
241 set_valid();
242 ASSERT((type_ & kIsNotStringMask) == kStringTag);
243}
244
245
246bool StringShape::IsSymbol() {
247 ASSERT(valid());
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000248 ASSERT(kSymbolTag != 0);
249 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000250}
251
252
ager@chromium.org5ec48922009-05-05 07:25:34 +0000253bool String::IsAsciiRepresentation() {
254 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000255 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000256}
257
258
ager@chromium.org5ec48922009-05-05 07:25:34 +0000259bool String::IsTwoByteRepresentation() {
260 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000261 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000262}
263
264
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000265bool String::HasOnlyAsciiChars() {
266 uint32_t type = map()->instance_type();
267 return (type & kStringEncodingMask) == kAsciiStringTag ||
268 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000269}
270
271
ager@chromium.org870a0b62008-11-04 11:43:05 +0000272bool StringShape::IsCons() {
273 return (type_ & kStringRepresentationMask) == kConsStringTag;
274}
275
276
ager@chromium.org870a0b62008-11-04 11:43:05 +0000277bool StringShape::IsExternal() {
278 return (type_ & kStringRepresentationMask) == kExternalStringTag;
279}
280
281
282bool StringShape::IsSequential() {
283 return (type_ & kStringRepresentationMask) == kSeqStringTag;
284}
285
286
287StringRepresentationTag StringShape::representation_tag() {
288 uint32_t tag = (type_ & kStringRepresentationMask);
289 return static_cast<StringRepresentationTag>(tag);
290}
291
292
293uint32_t StringShape::full_representation_tag() {
294 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
295}
296
297
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000298STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
299 Internals::kFullStringRepresentationMask);
300
301
ager@chromium.org870a0b62008-11-04 11:43:05 +0000302bool StringShape::IsSequentialAscii() {
303 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
304}
305
306
307bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000308 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000309}
310
311
312bool StringShape::IsExternalAscii() {
313 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
314}
315
316
317bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000318 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000319}
320
321
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000322STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
323 Internals::kExternalTwoByteRepresentationTag);
324
325
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000326uc32 FlatStringReader::Get(int index) {
327 ASSERT(0 <= index && index <= length_);
328 if (is_ascii_) {
329 return static_cast<const byte*>(start_)[index];
330 } else {
331 return static_cast<const uc16*>(start_)[index];
332 }
333}
334
335
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000336bool Object::IsNumber() {
337 return IsSmi() || IsHeapNumber();
338}
339
340
341bool Object::IsByteArray() {
342 return Object::IsHeapObject()
343 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
344}
345
346
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000347bool Object::IsExternalPixelArray() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000348 return Object::IsHeapObject() &&
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000349 HeapObject::cast(this)->map()->instance_type() ==
350 EXTERNAL_PIXEL_ARRAY_TYPE;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000351}
352
353
ager@chromium.org3811b432009-10-28 14:53:37 +0000354bool Object::IsExternalArray() {
355 if (!Object::IsHeapObject())
356 return false;
357 InstanceType instance_type =
358 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000359 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
360 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000361}
362
363
364bool Object::IsExternalByteArray() {
365 return Object::IsHeapObject() &&
366 HeapObject::cast(this)->map()->instance_type() ==
367 EXTERNAL_BYTE_ARRAY_TYPE;
368}
369
370
371bool Object::IsExternalUnsignedByteArray() {
372 return Object::IsHeapObject() &&
373 HeapObject::cast(this)->map()->instance_type() ==
374 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
375}
376
377
378bool Object::IsExternalShortArray() {
379 return Object::IsHeapObject() &&
380 HeapObject::cast(this)->map()->instance_type() ==
381 EXTERNAL_SHORT_ARRAY_TYPE;
382}
383
384
385bool Object::IsExternalUnsignedShortArray() {
386 return Object::IsHeapObject() &&
387 HeapObject::cast(this)->map()->instance_type() ==
388 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
389}
390
391
392bool Object::IsExternalIntArray() {
393 return Object::IsHeapObject() &&
394 HeapObject::cast(this)->map()->instance_type() ==
395 EXTERNAL_INT_ARRAY_TYPE;
396}
397
398
399bool Object::IsExternalUnsignedIntArray() {
400 return Object::IsHeapObject() &&
401 HeapObject::cast(this)->map()->instance_type() ==
402 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
403}
404
405
406bool Object::IsExternalFloatArray() {
407 return Object::IsHeapObject() &&
408 HeapObject::cast(this)->map()->instance_type() ==
409 EXTERNAL_FLOAT_ARRAY_TYPE;
410}
411
412
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000413bool Object::IsExternalDoubleArray() {
414 return Object::IsHeapObject() &&
415 HeapObject::cast(this)->map()->instance_type() ==
416 EXTERNAL_DOUBLE_ARRAY_TYPE;
417}
418
419
lrn@chromium.org303ada72010-10-27 09:33:13 +0000420bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000421 return HAS_FAILURE_TAG(this);
422}
423
424
lrn@chromium.org303ada72010-10-27 09:33:13 +0000425bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000426 return HAS_FAILURE_TAG(this)
427 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
428}
429
430
lrn@chromium.org303ada72010-10-27 09:33:13 +0000431bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000432 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000433 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000434}
435
436
lrn@chromium.org303ada72010-10-27 09:33:13 +0000437bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000438 return this == Failure::Exception();
439}
440
441
lrn@chromium.org303ada72010-10-27 09:33:13 +0000442bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000443 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000444}
445
446
447Failure* Failure::cast(MaybeObject* obj) {
448 ASSERT(HAS_FAILURE_TAG(obj));
449 return reinterpret_cast<Failure*>(obj);
450}
451
452
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000453bool Object::IsJSReceiver() {
454 return IsHeapObject() &&
455 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
456}
457
458
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000459bool Object::IsJSObject() {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000460 return IsJSReceiver() && !IsJSProxy();
461}
462
463
464bool Object::IsJSProxy() {
465 return Object::IsHeapObject() &&
466 (HeapObject::cast(this)->map()->instance_type() == JS_PROXY_TYPE ||
467 HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE);
468}
469
470
471bool Object::IsJSFunctionProxy() {
472 return Object::IsHeapObject() &&
473 HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000474}
475
476
ager@chromium.org32912102009-01-16 10:38:43 +0000477bool Object::IsJSContextExtensionObject() {
478 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000479 && (HeapObject::cast(this)->map()->instance_type() ==
480 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
ager@chromium.org32912102009-01-16 10:38:43 +0000481}
482
483
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000484bool Object::IsMap() {
485 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000486 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000487}
488
489
490bool Object::IsFixedArray() {
491 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000492 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000493}
494
495
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000496bool Object::IsFixedDoubleArray() {
497 return Object::IsHeapObject()
498 && HeapObject::cast(this)->map()->instance_type() ==
499 FIXED_DOUBLE_ARRAY_TYPE;
500}
501
502
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000503bool Object::IsDescriptorArray() {
504 return IsFixedArray();
505}
506
507
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000508bool Object::IsDeoptimizationInputData() {
509 // Must be a fixed array.
510 if (!IsFixedArray()) return false;
511
512 // There's no sure way to detect the difference between a fixed array and
513 // a deoptimization data array. Since this is used for asserts we can
514 // check that the length is zero or else the fixed size plus a multiple of
515 // the entry size.
516 int length = FixedArray::cast(this)->length();
517 if (length == 0) return true;
518
519 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
520 return length >= 0 &&
521 length % DeoptimizationInputData::kDeoptEntrySize == 0;
522}
523
524
525bool Object::IsDeoptimizationOutputData() {
526 if (!IsFixedArray()) return false;
527 // There's actually no way to see the difference between a fixed array and
528 // a deoptimization data array. Since this is used for asserts we can check
529 // that the length is plausible though.
530 if (FixedArray::cast(this)->length() % 2 != 0) return false;
531 return true;
532}
533
534
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000535bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000536 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000537 Map* map = HeapObject::cast(this)->map();
538 Heap* heap = map->GetHeap();
539 return (map == heap->function_context_map() ||
540 map == heap->catch_context_map() ||
541 map == heap->with_context_map() ||
542 map == heap->global_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000543 }
544 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000545}
546
547
548bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000549 return Object::IsHeapObject() &&
550 HeapObject::cast(this)->map() ==
551 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000552}
553
554
555bool Object::IsJSFunction() {
556 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000557 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000558}
559
560
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000561template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000562 return obj->IsJSFunction();
563}
564
565
566bool Object::IsCode() {
567 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000568 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000569}
570
571
572bool Object::IsOddball() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000573 ASSERT(HEAP->is_safe_to_read_maps());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000574 return Object::IsHeapObject()
575 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
576}
577
578
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000579bool Object::IsJSGlobalPropertyCell() {
580 return Object::IsHeapObject()
581 && HeapObject::cast(this)->map()->instance_type()
582 == JS_GLOBAL_PROPERTY_CELL_TYPE;
583}
584
585
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000586bool Object::IsSharedFunctionInfo() {
587 return Object::IsHeapObject() &&
588 (HeapObject::cast(this)->map()->instance_type() ==
589 SHARED_FUNCTION_INFO_TYPE);
590}
591
592
593bool Object::IsJSValue() {
594 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000595 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
596}
597
598
599bool Object::IsJSMessageObject() {
600 return Object::IsHeapObject()
601 && (HeapObject::cast(this)->map()->instance_type() ==
602 JS_MESSAGE_OBJECT_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000603}
604
605
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000606bool Object::IsStringWrapper() {
607 return IsJSValue() && JSValue::cast(this)->value()->IsString();
608}
609
610
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000611bool Object::IsForeign() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000612 return Object::IsHeapObject()
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000613 && HeapObject::cast(this)->map()->instance_type() == FOREIGN_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000614}
615
616
617bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000618 return IsOddball() &&
619 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000620}
621
622
623bool Object::IsJSArray() {
624 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000625 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000626}
627
628
ager@chromium.org236ad962008-09-25 09:45:57 +0000629bool Object::IsJSRegExp() {
630 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000631 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
ager@chromium.org236ad962008-09-25 09:45:57 +0000632}
633
634
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000635template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000636 return obj->IsJSArray();
637}
638
639
640bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000641 return Object::IsHeapObject() &&
642 HeapObject::cast(this)->map() ==
643 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000644}
645
646
647bool Object::IsDictionary() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000648 return IsHashTable() && this !=
649 HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000650}
651
652
653bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000654 return IsHashTable() && this ==
655 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000656}
657
658
ager@chromium.orgac091b72010-05-05 07:34:42 +0000659bool Object::IsJSFunctionResultCache() {
660 if (!IsFixedArray()) return false;
661 FixedArray* self = FixedArray::cast(this);
662 int length = self->length();
663 if (length < JSFunctionResultCache::kEntriesIndex) return false;
664 if ((length - JSFunctionResultCache::kEntriesIndex)
665 % JSFunctionResultCache::kEntrySize != 0) {
666 return false;
667 }
668#ifdef DEBUG
669 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
670#endif
671 return true;
672}
673
674
ricow@chromium.org65fae842010-08-25 15:26:24 +0000675bool Object::IsNormalizedMapCache() {
676 if (!IsFixedArray()) return false;
677 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
678 return false;
679 }
680#ifdef DEBUG
681 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
682#endif
683 return true;
684}
685
686
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000687bool Object::IsCompilationCacheTable() {
688 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000689}
690
691
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000692bool Object::IsCodeCacheHashTable() {
693 return IsHashTable();
694}
695
696
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000697bool Object::IsPolymorphicCodeCacheHashTable() {
698 return IsHashTable();
699}
700
701
ager@chromium.org236ad962008-09-25 09:45:57 +0000702bool Object::IsMapCache() {
703 return IsHashTable();
704}
705
706
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000707bool Object::IsPrimitive() {
708 return IsOddball() || IsNumber() || IsString();
709}
710
711
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000712bool Object::IsJSGlobalProxy() {
713 bool result = IsHeapObject() &&
714 (HeapObject::cast(this)->map()->instance_type() ==
715 JS_GLOBAL_PROXY_TYPE);
716 ASSERT(!result || IsAccessCheckNeeded());
717 return result;
718}
719
720
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000721bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000722 if (!IsHeapObject()) return false;
723
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000724 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000725 return type == JS_GLOBAL_OBJECT_TYPE ||
726 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000727}
728
729
730bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000731 return IsHeapObject() &&
732 (HeapObject::cast(this)->map()->instance_type() ==
733 JS_GLOBAL_OBJECT_TYPE);
734}
735
736
737bool Object::IsJSBuiltinsObject() {
738 return IsHeapObject() &&
739 (HeapObject::cast(this)->map()->instance_type() ==
740 JS_BUILTINS_OBJECT_TYPE);
741}
742
743
744bool Object::IsUndetectableObject() {
745 return IsHeapObject()
746 && HeapObject::cast(this)->map()->is_undetectable();
747}
748
749
750bool Object::IsAccessCheckNeeded() {
751 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000752 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000753}
754
755
756bool Object::IsStruct() {
757 if (!IsHeapObject()) return false;
758 switch (HeapObject::cast(this)->map()->instance_type()) {
759#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
760 STRUCT_LIST(MAKE_STRUCT_CASE)
761#undef MAKE_STRUCT_CASE
762 default: return false;
763 }
764}
765
766
767#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
768 bool Object::Is##Name() { \
769 return Object::IsHeapObject() \
770 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
771 }
772 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
773#undef MAKE_STRUCT_PREDICATE
774
775
776bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000777 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000778}
779
780
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000781bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000782 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
783}
784
785
786bool Object::IsTheHole() {
787 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000788}
789
790
791bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000792 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000793}
794
795
796bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000797 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000798}
799
800
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000801bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000802 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000803}
804
805
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000806double Object::Number() {
807 ASSERT(IsNumber());
808 return IsSmi()
809 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
810 : reinterpret_cast<HeapNumber*>(this)->value();
811}
812
813
lrn@chromium.org303ada72010-10-27 09:33:13 +0000814MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000815 if (IsSmi()) return this;
816 if (IsHeapNumber()) {
817 double value = HeapNumber::cast(this)->value();
818 int int_value = FastD2I(value);
819 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
820 return Smi::FromInt(int_value);
821 }
822 }
823 return Failure::Exception();
824}
825
826
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000827bool Object::HasSpecificClassOf(String* name) {
828 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
829}
830
831
lrn@chromium.org303ada72010-10-27 09:33:13 +0000832MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000833 // GetElement can trigger a getter which can cause allocation.
834 // This was not always the case. This ASSERT is here to catch
835 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000836 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000837 return GetElementWithReceiver(this, index);
838}
839
840
lrn@chromium.org303ada72010-10-27 09:33:13 +0000841Object* Object::GetElementNoExceptionThrown(uint32_t index) {
842 MaybeObject* maybe = GetElementWithReceiver(this, index);
843 ASSERT(!maybe->IsFailure());
844 Object* result = NULL; // Initialization to please compiler.
845 maybe->ToObject(&result);
846 return result;
847}
848
849
850MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000851 PropertyAttributes attributes;
852 return GetPropertyWithReceiver(this, key, &attributes);
853}
854
855
lrn@chromium.org303ada72010-10-27 09:33:13 +0000856MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000857 return GetPropertyWithReceiver(this, key, attributes);
858}
859
860
861#define FIELD_ADDR(p, offset) \
862 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
863
864#define READ_FIELD(p, offset) \
865 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
866
867#define WRITE_FIELD(p, offset, value) \
868 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
869
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000870// TODO(isolates): Pass heap in to these macros.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000871#define WRITE_BARRIER(object, offset) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000872 object->GetHeap()->RecordWrite(object->address(), offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000873
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000874// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000875// write due to the assert validating the written value.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000876#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, mode) \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000877 if (mode == UPDATE_WRITE_BARRIER) { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000878 heap->RecordWrite(object->address(), offset); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000879 } else { \
880 ASSERT(mode == SKIP_WRITE_BARRIER); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000881 ASSERT(heap->InNewSpace(object) || \
882 !heap->InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000883 Page::FromAddress(object->address())-> \
884 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000885 }
886
lrn@chromium.org7516f052011-03-30 08:52:27 +0000887#ifndef V8_TARGET_ARCH_MIPS
888 #define READ_DOUBLE_FIELD(p, offset) \
889 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
890#else // V8_TARGET_ARCH_MIPS
891 // Prevent gcc from using load-double (mips ldc1) on (possibly)
892 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000893 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000894 union conversion {
895 double d;
896 uint32_t u[2];
897 } c;
898 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
899 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
900 return c.d;
901 }
902 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
903#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000904
lrn@chromium.org7516f052011-03-30 08:52:27 +0000905
906#ifndef V8_TARGET_ARCH_MIPS
907 #define WRITE_DOUBLE_FIELD(p, offset, value) \
908 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
909#else // V8_TARGET_ARCH_MIPS
910 // Prevent gcc from using store-double (mips sdc1) on (possibly)
911 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000912 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000913 double value) {
914 union conversion {
915 double d;
916 uint32_t u[2];
917 } c;
918 c.d = value;
919 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
920 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
921 }
922 #define WRITE_DOUBLE_FIELD(p, offset, value) \
923 write_double_field(p, offset, value)
924#endif // V8_TARGET_ARCH_MIPS
925
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000926
927#define READ_INT_FIELD(p, offset) \
928 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
929
930#define WRITE_INT_FIELD(p, offset, value) \
931 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
932
ager@chromium.org3e875802009-06-29 08:26:34 +0000933#define READ_INTPTR_FIELD(p, offset) \
934 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
935
936#define WRITE_INTPTR_FIELD(p, offset, value) \
937 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
938
ager@chromium.org7c537e22008-10-16 08:43:32 +0000939#define READ_UINT32_FIELD(p, offset) \
940 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
941
942#define WRITE_UINT32_FIELD(p, offset, value) \
943 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
944
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000945#define READ_SHORT_FIELD(p, offset) \
946 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
947
948#define WRITE_SHORT_FIELD(p, offset, value) \
949 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
950
951#define READ_BYTE_FIELD(p, offset) \
952 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
953
954#define WRITE_BYTE_FIELD(p, offset, value) \
955 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
956
957
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000958Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
959 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000960}
961
962
963int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000964 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000965}
966
967
968Smi* Smi::FromInt(int value) {
969 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000970 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000971 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000972 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000973 return reinterpret_cast<Smi*>(tagged_value);
974}
975
976
977Smi* Smi::FromIntptr(intptr_t value) {
978 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000979 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
980 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000981}
982
983
984Failure::Type Failure::type() const {
985 return static_cast<Type>(value() & kFailureTypeTagMask);
986}
987
988
989bool Failure::IsInternalError() const {
990 return type() == INTERNAL_ERROR;
991}
992
993
994bool Failure::IsOutOfMemoryException() const {
995 return type() == OUT_OF_MEMORY_EXCEPTION;
996}
997
998
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000999AllocationSpace Failure::allocation_space() const {
1000 ASSERT_EQ(RETRY_AFTER_GC, type());
1001 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1002 & kSpaceTagMask);
1003}
1004
1005
1006Failure* Failure::InternalError() {
1007 return Construct(INTERNAL_ERROR);
1008}
1009
1010
1011Failure* Failure::Exception() {
1012 return Construct(EXCEPTION);
1013}
1014
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001015
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001016Failure* Failure::OutOfMemoryException() {
1017 return Construct(OUT_OF_MEMORY_EXCEPTION);
1018}
1019
1020
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001021intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001022 return static_cast<intptr_t>(
1023 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001024}
1025
1026
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001027Failure* Failure::RetryAfterGC() {
1028 return RetryAfterGC(NEW_SPACE);
1029}
1030
1031
1032Failure* Failure::RetryAfterGC(AllocationSpace space) {
1033 ASSERT((space & ~kSpaceTagMask) == 0);
1034 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001035}
1036
1037
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001038Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001039 uintptr_t info =
1040 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001041 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001042 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001043}
1044
1045
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001046bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001047#ifdef DEBUG
1048 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1049#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001050
1051#ifdef V8_TARGET_ARCH_X64
1052 // To be representable as a long smi, the value must be a 32-bit integer.
1053 bool result = (value == static_cast<int32_t>(value));
1054#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001055 // To be representable as an tagged small integer, the two
1056 // most-significant bits of 'value' must be either 00 or 11 due to
1057 // sign-extension. To check this we add 01 to the two
1058 // most-significant bits, and check if the most-significant bit is 0
1059 //
1060 // CAUTION: The original code below:
1061 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1062 // may lead to incorrect results according to the C language spec, and
1063 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1064 // compiler may produce undefined results in case of signed integer
1065 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001066 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001067#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001068 ASSERT(result == in_range);
1069 return result;
1070}
1071
1072
kasper.lund7276f142008-07-30 08:49:36 +00001073MapWord MapWord::FromMap(Map* map) {
1074 return MapWord(reinterpret_cast<uintptr_t>(map));
1075}
1076
1077
1078Map* MapWord::ToMap() {
1079 return reinterpret_cast<Map*>(value_);
1080}
1081
1082
1083bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001084 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001085}
1086
1087
1088MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001089 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1090 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001091}
1092
1093
1094HeapObject* MapWord::ToForwardingAddress() {
1095 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001096 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001097}
1098
1099
1100bool MapWord::IsMarked() {
1101 return (value_ & kMarkingMask) == 0;
1102}
1103
1104
1105void MapWord::SetMark() {
1106 value_ &= ~kMarkingMask;
1107}
1108
1109
1110void MapWord::ClearMark() {
1111 value_ |= kMarkingMask;
1112}
1113
1114
1115bool MapWord::IsOverflowed() {
1116 return (value_ & kOverflowMask) != 0;
1117}
1118
1119
1120void MapWord::SetOverflow() {
1121 value_ |= kOverflowMask;
1122}
1123
1124
1125void MapWord::ClearOverflow() {
1126 value_ &= ~kOverflowMask;
1127}
1128
1129
1130MapWord MapWord::EncodeAddress(Address map_address, int offset) {
1131 // Offset is the distance in live bytes from the first live object in the
1132 // same page. The offset between two objects in the same page should not
1133 // exceed the object area size of a page.
1134 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1135
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001136 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001137 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1138
1139 Page* map_page = Page::FromAddress(map_address);
1140 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1141
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001142 uintptr_t map_page_offset =
1143 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001144
1145 uintptr_t encoding =
1146 (compact_offset << kForwardingOffsetShift) |
1147 (map_page_offset << kMapPageOffsetShift) |
1148 (map_page->mc_page_index << kMapPageIndexShift);
1149 return MapWord(encoding);
1150}
1151
1152
1153Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001154 int map_page_index =
1155 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001156 ASSERT_MAP_PAGE_INDEX(map_page_index);
1157
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001158 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001159 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1160 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001161
1162 return (map_space->PageAddress(map_page_index) + map_page_offset);
1163}
1164
1165
1166int MapWord::DecodeOffset() {
1167 // The offset field is represented in the kForwardingOffsetBits
1168 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001169 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1170 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1171 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001172}
1173
1174
1175MapWord MapWord::FromEncodedAddress(Address address) {
1176 return MapWord(reinterpret_cast<uintptr_t>(address));
1177}
1178
1179
1180Address MapWord::ToEncodedAddress() {
1181 return reinterpret_cast<Address>(value_);
1182}
1183
1184
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001185#ifdef DEBUG
1186void HeapObject::VerifyObjectField(int offset) {
1187 VerifyPointer(READ_FIELD(this, offset));
1188}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001189
1190void HeapObject::VerifySmiField(int offset) {
1191 ASSERT(READ_FIELD(this, offset)->IsSmi());
1192}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001193#endif
1194
1195
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001196Heap* HeapObject::GetHeap() {
1197 // During GC, the map pointer in HeapObject is used in various ways that
1198 // prevent us from retrieving Heap from the map.
1199 // Assert that we are not in GC, implement GC code in a way that it doesn't
1200 // pull heap from the map.
1201 ASSERT(HEAP->is_safe_to_read_maps());
1202 return map()->heap();
1203}
1204
1205
1206Isolate* HeapObject::GetIsolate() {
1207 return GetHeap()->isolate();
1208}
1209
1210
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001211Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001212 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001213}
1214
1215
1216void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001217 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001218}
1219
1220
kasper.lund7276f142008-07-30 08:49:36 +00001221MapWord HeapObject::map_word() {
1222 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1223}
1224
1225
1226void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001227 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001228 // here.
1229 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1230}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001231
1232
1233HeapObject* HeapObject::FromAddress(Address address) {
1234 ASSERT_TAG_ALIGNED(address);
1235 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1236}
1237
1238
1239Address HeapObject::address() {
1240 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1241}
1242
1243
1244int HeapObject::Size() {
1245 return SizeFromMap(map());
1246}
1247
1248
1249void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1250 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1251 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1252}
1253
1254
1255void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1256 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1257}
1258
1259
kasper.lund7276f142008-07-30 08:49:36 +00001260bool HeapObject::IsMarked() {
1261 return map_word().IsMarked();
1262}
1263
1264
1265void HeapObject::SetMark() {
1266 ASSERT(!IsMarked());
1267 MapWord first_word = map_word();
1268 first_word.SetMark();
1269 set_map_word(first_word);
1270}
1271
1272
1273void HeapObject::ClearMark() {
1274 ASSERT(IsMarked());
1275 MapWord first_word = map_word();
1276 first_word.ClearMark();
1277 set_map_word(first_word);
1278}
1279
1280
1281bool HeapObject::IsOverflowed() {
1282 return map_word().IsOverflowed();
1283}
1284
1285
1286void HeapObject::SetOverflow() {
1287 MapWord first_word = map_word();
1288 first_word.SetOverflow();
1289 set_map_word(first_word);
1290}
1291
1292
1293void HeapObject::ClearOverflow() {
1294 ASSERT(IsOverflowed());
1295 MapWord first_word = map_word();
1296 first_word.ClearOverflow();
1297 set_map_word(first_word);
1298}
1299
1300
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001301double HeapNumber::value() {
1302 return READ_DOUBLE_FIELD(this, kValueOffset);
1303}
1304
1305
1306void HeapNumber::set_value(double value) {
1307 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1308}
1309
1310
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001311int HeapNumber::get_exponent() {
1312 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1313 kExponentShift) - kExponentBias;
1314}
1315
1316
1317int HeapNumber::get_sign() {
1318 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1319}
1320
1321
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001322ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001323
1324
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001325HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001326 Object* array = READ_FIELD(this, kElementsOffset);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001327 ASSERT(array->HasValidElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001328 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001329}
1330
1331
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001332void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001333 ASSERT(map()->has_fast_elements() ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001334 (value->map() == GetHeap()->fixed_array_map() ||
1335 value->map() == GetHeap()->fixed_cow_array_map()));
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001336 ASSERT(value->HasValidElements());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001337 WRITE_FIELD(this, kElementsOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001338 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001339}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001340
1341
1342void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001343 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1344 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001345}
1346
1347
1348void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001349 ASSERT(map()->has_fast_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001350 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1351 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001352}
1353
1354
lrn@chromium.org303ada72010-10-27 09:33:13 +00001355MaybeObject* JSObject::ResetElements() {
1356 Object* obj;
1357 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
1358 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1359 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001360 set_map(Map::cast(obj));
1361 initialize_elements();
1362 return this;
1363}
1364
1365
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001366ACCESSORS(Oddball, to_string, String, kToStringOffset)
1367ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1368
1369
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001370byte Oddball::kind() {
1371 return READ_BYTE_FIELD(this, kKindOffset);
1372}
1373
1374
1375void Oddball::set_kind(byte value) {
1376 WRITE_BYTE_FIELD(this, kKindOffset, value);
1377}
1378
1379
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001380Object* JSGlobalPropertyCell::value() {
1381 return READ_FIELD(this, kValueOffset);
1382}
1383
1384
1385void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1386 // The write barrier is not used for global property cells.
1387 ASSERT(!val->IsJSGlobalPropertyCell());
1388 WRITE_FIELD(this, kValueOffset, val);
1389}
1390
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001391
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001392int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001393 InstanceType type = map()->instance_type();
1394 // Check for the most common kind of JavaScript object before
1395 // falling into the generic switch. This speeds up the internal
1396 // field operations considerably on average.
1397 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1398 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001399 case JS_GLOBAL_PROXY_TYPE:
1400 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001401 case JS_GLOBAL_OBJECT_TYPE:
1402 return JSGlobalObject::kSize;
1403 case JS_BUILTINS_OBJECT_TYPE:
1404 return JSBuiltinsObject::kSize;
1405 case JS_FUNCTION_TYPE:
1406 return JSFunction::kSize;
1407 case JS_VALUE_TYPE:
1408 return JSValue::kSize;
1409 case JS_ARRAY_TYPE:
1410 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001411 case JS_REGEXP_TYPE:
1412 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001413 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001414 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001415 case JS_MESSAGE_OBJECT_TYPE:
1416 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001417 default:
1418 UNREACHABLE();
1419 return 0;
1420 }
1421}
1422
1423
1424int JSObject::GetInternalFieldCount() {
1425 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001426 // Make sure to adjust for the number of in-object properties. These
1427 // properties do contribute to the size, but are not internal fields.
1428 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1429 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001430}
1431
1432
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001433int JSObject::GetInternalFieldOffset(int index) {
1434 ASSERT(index < GetInternalFieldCount() && index >= 0);
1435 return GetHeaderSize() + (kPointerSize * index);
1436}
1437
1438
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001439Object* JSObject::GetInternalField(int index) {
1440 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001441 // Internal objects do follow immediately after the header, whereas in-object
1442 // properties are at the end of the object. Therefore there is no need
1443 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001444 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1445}
1446
1447
1448void JSObject::SetInternalField(int index, Object* value) {
1449 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001450 // Internal objects do follow immediately after the header, whereas in-object
1451 // properties are at the end of the object. Therefore there is no need
1452 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001453 int offset = GetHeaderSize() + (kPointerSize * index);
1454 WRITE_FIELD(this, offset, value);
1455 WRITE_BARRIER(this, offset);
1456}
1457
1458
ager@chromium.org7c537e22008-10-16 08:43:32 +00001459// Access fast-case object properties at index. The use of these routines
1460// is needed to correctly distinguish between properties stored in-object and
1461// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001462Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001463 // Adjust for the number of properties stored in the object.
1464 index -= map()->inobject_properties();
1465 if (index < 0) {
1466 int offset = map()->instance_size() + (index * kPointerSize);
1467 return READ_FIELD(this, offset);
1468 } else {
1469 ASSERT(index < properties()->length());
1470 return properties()->get(index);
1471 }
1472}
1473
1474
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001475Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001476 // Adjust for the number of properties stored in the object.
1477 index -= map()->inobject_properties();
1478 if (index < 0) {
1479 int offset = map()->instance_size() + (index * kPointerSize);
1480 WRITE_FIELD(this, offset, value);
1481 WRITE_BARRIER(this, offset);
1482 } else {
1483 ASSERT(index < properties()->length());
1484 properties()->set(index, value);
1485 }
1486 return value;
1487}
1488
1489
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001490int JSObject::GetInObjectPropertyOffset(int index) {
1491 // Adjust for the number of properties stored in the object.
1492 index -= map()->inobject_properties();
1493 ASSERT(index < 0);
1494 return map()->instance_size() + (index * kPointerSize);
1495}
1496
1497
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001498Object* JSObject::InObjectPropertyAt(int index) {
1499 // Adjust for the number of properties stored in the object.
1500 index -= map()->inobject_properties();
1501 ASSERT(index < 0);
1502 int offset = map()->instance_size() + (index * kPointerSize);
1503 return READ_FIELD(this, offset);
1504}
1505
1506
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001507Object* JSObject::InObjectPropertyAtPut(int index,
1508 Object* value,
1509 WriteBarrierMode mode) {
1510 // Adjust for the number of properties stored in the object.
1511 index -= map()->inobject_properties();
1512 ASSERT(index < 0);
1513 int offset = map()->instance_size() + (index * kPointerSize);
1514 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001515 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001516 return value;
1517}
1518
1519
1520
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001521void JSObject::InitializeBody(int object_size, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001522 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001523 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001524 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001525 }
1526}
1527
1528
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001529bool JSObject::HasFastProperties() {
1530 return !properties()->IsDictionary();
1531}
1532
1533
1534int JSObject::MaxFastProperties() {
1535 // Allow extra fast properties if the object has more than
1536 // kMaxFastProperties in-object properties. When this is the case,
1537 // it is very unlikely that the object is being used as a dictionary
1538 // and there is a good chance that allowing more map transitions
1539 // will be worth it.
1540 return Max(map()->inobject_properties(), kMaxFastProperties);
1541}
1542
1543
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001544void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001545 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001546 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001547 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001548 }
1549}
1550
1551
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001552bool Object::ToArrayIndex(uint32_t* index) {
1553 if (IsSmi()) {
1554 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001555 if (value < 0) return false;
1556 *index = value;
1557 return true;
1558 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001559 if (IsHeapNumber()) {
1560 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001561 uint32_t uint_value = static_cast<uint32_t>(value);
1562 if (value == static_cast<double>(uint_value)) {
1563 *index = uint_value;
1564 return true;
1565 }
1566 }
1567 return false;
1568}
1569
1570
1571bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1572 if (!this->IsJSValue()) return false;
1573
1574 JSValue* js_value = JSValue::cast(this);
1575 if (!js_value->value()->IsString()) return false;
1576
1577 String* str = String::cast(js_value->value());
1578 if (index >= (uint32_t)str->length()) return false;
1579
1580 return true;
1581}
1582
1583
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001584FixedArrayBase* FixedArrayBase::cast(Object* object) {
1585 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1586 return reinterpret_cast<FixedArrayBase*>(object);
1587}
1588
1589
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001590Object* FixedArray::get(int index) {
1591 ASSERT(index >= 0 && index < this->length());
1592 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1593}
1594
1595
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001596void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001597 ASSERT(map() != HEAP->fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001598 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1599 int offset = kHeaderSize + index * kPointerSize;
1600 WRITE_FIELD(this, offset, value);
1601}
1602
1603
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001604void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001605 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001606 ASSERT(index >= 0 && index < this->length());
1607 int offset = kHeaderSize + index * kPointerSize;
1608 WRITE_FIELD(this, offset, value);
1609 WRITE_BARRIER(this, offset);
1610}
1611
1612
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001613double FixedDoubleArray::get(int index) {
1614 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1615 map() != HEAP->fixed_array_map());
1616 ASSERT(index >= 0 && index < this->length());
1617 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1618 ASSERT(!is_the_hole_nan(result));
1619 return result;
1620}
1621
1622
1623void FixedDoubleArray::set(int index, double value) {
1624 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1625 map() != HEAP->fixed_array_map());
1626 int offset = kHeaderSize + index * kDoubleSize;
1627 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1628 WRITE_DOUBLE_FIELD(this, offset, value);
1629}
1630
1631
1632void FixedDoubleArray::set_the_hole(int index) {
1633 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1634 map() != HEAP->fixed_array_map());
1635 int offset = kHeaderSize + index * kDoubleSize;
1636 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1637}
1638
1639
1640bool FixedDoubleArray::is_the_hole(int index) {
1641 int offset = kHeaderSize + index * kDoubleSize;
1642 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1643}
1644
1645
1646void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1647 int old_length = from->length();
1648 ASSERT(old_length < length());
1649 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1650 FIELD_ADDR(from, kHeaderSize),
1651 old_length * kDoubleSize);
1652 int offset = kHeaderSize + old_length * kDoubleSize;
1653 for (int current = from->length(); current < length(); ++current) {
1654 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1655 offset += kDoubleSize;
1656 }
1657}
1658
1659
1660void FixedDoubleArray::Initialize(FixedArray* from) {
1661 int old_length = from->length();
1662 ASSERT(old_length < length());
1663 for (int i = 0; i < old_length; i++) {
1664 Object* hole_or_object = from->get(i);
1665 if (hole_or_object->IsTheHole()) {
1666 set_the_hole(i);
1667 } else {
1668 set(i, hole_or_object->Number());
1669 }
1670 }
1671 int offset = kHeaderSize + old_length * kDoubleSize;
1672 for (int current = from->length(); current < length(); ++current) {
1673 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1674 offset += kDoubleSize;
1675 }
1676}
1677
1678
1679void FixedDoubleArray::Initialize(NumberDictionary* from) {
1680 int offset = kHeaderSize;
1681 for (int current = 0; current < length(); ++current) {
1682 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1683 offset += kDoubleSize;
1684 }
1685 for (int i = 0; i < from->Capacity(); i++) {
1686 Object* key = from->KeyAt(i);
1687 if (key->IsNumber()) {
1688 uint32_t entry = static_cast<uint32_t>(key->Number());
1689 set(entry, from->ValueAt(i)->Number());
1690 }
1691 }
1692}
1693
1694
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001695WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001696 if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001697 return UPDATE_WRITE_BARRIER;
1698}
1699
1700
1701void FixedArray::set(int index,
1702 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001703 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001704 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001705 ASSERT(index >= 0 && index < this->length());
1706 int offset = kHeaderSize + index * kPointerSize;
1707 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001708 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001709}
1710
1711
1712void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001713 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001714 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001715 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001716 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1717}
1718
1719
1720void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001721 ASSERT(map() != HEAP->fixed_cow_array_map());
1722 set_undefined(GetHeap(), index);
1723}
1724
1725
1726void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001727 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001728 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001729 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001730 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001731}
1732
1733
ager@chromium.org236ad962008-09-25 09:45:57 +00001734void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001735 set_null(GetHeap(), index);
1736}
1737
1738
1739void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001740 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001741 ASSERT(!heap->InNewSpace(heap->null_value()));
1742 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001743}
1744
1745
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001746void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001747 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001748 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001749 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1750 WRITE_FIELD(this,
1751 kHeaderSize + index * kPointerSize,
1752 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001753}
1754
1755
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001756void FixedArray::set_unchecked(int index, Smi* value) {
1757 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1758 int offset = kHeaderSize + index * kPointerSize;
1759 WRITE_FIELD(this, offset, value);
1760}
1761
1762
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001763void FixedArray::set_unchecked(Heap* heap,
1764 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001765 Object* value,
1766 WriteBarrierMode mode) {
1767 int offset = kHeaderSize + index * kPointerSize;
1768 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001769 CONDITIONAL_WRITE_BARRIER(heap, this, offset, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001770}
1771
1772
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001773void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001774 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001775 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1776 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001777}
1778
1779
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001780Object** FixedArray::data_start() {
1781 return HeapObject::RawField(this, kHeaderSize);
1782}
1783
1784
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001785bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001786 ASSERT(this->IsSmi() ||
1787 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001788 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001789 return this->IsSmi() || length() <= kFirstIndex;
1790}
1791
1792
1793int DescriptorArray::bit_field3_storage() {
1794 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1795 return Smi::cast(storage)->value();
1796}
1797
1798void DescriptorArray::set_bit_field3_storage(int value) {
1799 ASSERT(!IsEmpty());
1800 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001801}
1802
1803
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001804void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1805 Object* tmp = array->get(first);
1806 fast_set(array, first, array->get(second));
1807 fast_set(array, second, tmp);
1808}
1809
1810
1811int DescriptorArray::Search(String* name) {
1812 SLOW_ASSERT(IsSortedNoDuplicates());
1813
1814 // Check for empty descriptor array.
1815 int nof = number_of_descriptors();
1816 if (nof == 0) return kNotFound;
1817
1818 // Fast case: do linear search for small arrays.
1819 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001820 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001821 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001822 }
1823
1824 // Slow case: perform binary search.
1825 return BinarySearch(name, 0, nof - 1);
1826}
1827
1828
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001829int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001830 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001831 if (number == DescriptorLookupCache::kAbsent) {
1832 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001833 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001834 }
1835 return number;
1836}
1837
1838
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001839String* DescriptorArray::GetKey(int descriptor_number) {
1840 ASSERT(descriptor_number < number_of_descriptors());
1841 return String::cast(get(ToKeyIndex(descriptor_number)));
1842}
1843
1844
1845Object* DescriptorArray::GetValue(int descriptor_number) {
1846 ASSERT(descriptor_number < number_of_descriptors());
1847 return GetContentArray()->get(ToValueIndex(descriptor_number));
1848}
1849
1850
1851Smi* DescriptorArray::GetDetails(int descriptor_number) {
1852 ASSERT(descriptor_number < number_of_descriptors());
1853 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1854}
1855
1856
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001857PropertyType DescriptorArray::GetType(int descriptor_number) {
1858 ASSERT(descriptor_number < number_of_descriptors());
1859 return PropertyDetails(GetDetails(descriptor_number)).type();
1860}
1861
1862
1863int DescriptorArray::GetFieldIndex(int descriptor_number) {
1864 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1865}
1866
1867
1868JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1869 return JSFunction::cast(GetValue(descriptor_number));
1870}
1871
1872
1873Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1874 ASSERT(GetType(descriptor_number) == CALLBACKS);
1875 return GetValue(descriptor_number);
1876}
1877
1878
1879AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1880 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001881 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
1882 return reinterpret_cast<AccessorDescriptor*>(p->address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001883}
1884
1885
1886bool DescriptorArray::IsProperty(int descriptor_number) {
1887 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1888}
1889
1890
1891bool DescriptorArray::IsTransition(int descriptor_number) {
1892 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001893 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
1894 t == EXTERNAL_ARRAY_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001895}
1896
1897
1898bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1899 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1900}
1901
1902
1903bool DescriptorArray::IsDontEnum(int descriptor_number) {
1904 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1905}
1906
1907
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001908void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1909 desc->Init(GetKey(descriptor_number),
1910 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001911 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001912}
1913
1914
1915void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1916 // Range check.
1917 ASSERT(descriptor_number < number_of_descriptors());
1918
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001919 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001920 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1921 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001922
1923 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1924 FixedArray* content_array = GetContentArray();
1925 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1926 fast_set(content_array, ToDetailsIndex(descriptor_number),
1927 desc->GetDetails().AsSmi());
1928}
1929
1930
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001931void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1932 Descriptor desc;
1933 src->Get(src_index, &desc);
1934 Set(index, &desc);
1935}
1936
1937
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001938void DescriptorArray::Swap(int first, int second) {
1939 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1940 FixedArray* content_array = GetContentArray();
1941 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1942 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1943}
1944
1945
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001946template<typename Shape, typename Key>
1947int HashTable<Shape, Key>::FindEntry(Key key) {
1948 return FindEntry(GetIsolate(), key);
1949}
1950
1951
1952// Find entry for key otherwise return kNotFound.
1953template<typename Shape, typename Key>
1954int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
1955 uint32_t capacity = Capacity();
1956 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
1957 uint32_t count = 1;
1958 // EnsureCapacity will guarantee the hash table is never full.
1959 while (true) {
1960 Object* element = KeyAt(entry);
1961 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
1962 if (element != isolate->heap()->null_value() &&
1963 Shape::IsMatch(key, element)) return entry;
1964 entry = NextProbe(entry, count++, capacity);
1965 }
1966 return kNotFound;
1967}
1968
1969
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001970bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001971 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001972 if (!max_index_object->IsSmi()) return false;
1973 return 0 !=
1974 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1975}
1976
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001977uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001978 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001979 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001980 if (!max_index_object->IsSmi()) return 0;
1981 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1982 return value >> kRequiresSlowElementsTagSize;
1983}
1984
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001985void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001986 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001987}
1988
1989
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001990// ------------------------------------
1991// Cast operations
1992
1993
1994CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001995CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001996CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001997CAST_ACCESSOR(DeoptimizationInputData)
1998CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001999CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002000CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002001CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002002CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002003CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002004CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002005CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002006CAST_ACCESSOR(String)
2007CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002008CAST_ACCESSOR(SeqAsciiString)
2009CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002010CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002011CAST_ACCESSOR(ExternalString)
2012CAST_ACCESSOR(ExternalAsciiString)
2013CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002014CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002015CAST_ACCESSOR(JSObject)
2016CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002017CAST_ACCESSOR(HeapObject)
2018CAST_ACCESSOR(HeapNumber)
2019CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002020CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002021CAST_ACCESSOR(SharedFunctionInfo)
2022CAST_ACCESSOR(Map)
2023CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002024CAST_ACCESSOR(GlobalObject)
2025CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002026CAST_ACCESSOR(JSGlobalObject)
2027CAST_ACCESSOR(JSBuiltinsObject)
2028CAST_ACCESSOR(Code)
2029CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002030CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002031CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002032CAST_ACCESSOR(JSFunctionProxy)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002033CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002034CAST_ACCESSOR(ByteArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00002035CAST_ACCESSOR(ExternalArray)
2036CAST_ACCESSOR(ExternalByteArray)
2037CAST_ACCESSOR(ExternalUnsignedByteArray)
2038CAST_ACCESSOR(ExternalShortArray)
2039CAST_ACCESSOR(ExternalUnsignedShortArray)
2040CAST_ACCESSOR(ExternalIntArray)
2041CAST_ACCESSOR(ExternalUnsignedIntArray)
2042CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002043CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002044CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002045CAST_ACCESSOR(Struct)
2046
2047
2048#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2049 STRUCT_LIST(MAKE_STRUCT_CAST)
2050#undef MAKE_STRUCT_CAST
2051
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002052
2053template <typename Shape, typename Key>
2054HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002055 ASSERT(obj->IsHashTable());
2056 return reinterpret_cast<HashTable*>(obj);
2057}
2058
2059
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002060SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002061SMI_ACCESSORS(ByteArray, length, kLengthOffset)
2062
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002063INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002064
2065
ager@chromium.orgac091b72010-05-05 07:34:42 +00002066SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002067
2068
2069uint32_t String::hash_field() {
2070 return READ_UINT32_FIELD(this, kHashFieldOffset);
2071}
2072
2073
2074void String::set_hash_field(uint32_t value) {
2075 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002076#if V8_HOST_ARCH_64_BIT
2077 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2078#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002079}
2080
2081
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002082bool String::Equals(String* other) {
2083 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002084 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2085 return false;
2086 }
2087 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002088}
2089
2090
lrn@chromium.org303ada72010-10-27 09:33:13 +00002091MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002092 if (!StringShape(this).IsCons()) return this;
2093 ConsString* cons = ConsString::cast(this);
2094 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002095 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002096}
2097
2098
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002099String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002100 MaybeObject* flat = TryFlatten(pretenure);
2101 Object* successfully_flattened;
2102 if (flat->ToObject(&successfully_flattened)) {
2103 return String::cast(successfully_flattened);
2104 }
2105 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002106}
2107
2108
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002109uint16_t String::Get(int index) {
2110 ASSERT(index >= 0 && index < length());
2111 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002112 case kSeqStringTag | kAsciiStringTag:
2113 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2114 case kSeqStringTag | kTwoByteStringTag:
2115 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2116 case kConsStringTag | kAsciiStringTag:
2117 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002118 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002119 case kExternalStringTag | kAsciiStringTag:
2120 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2121 case kExternalStringTag | kTwoByteStringTag:
2122 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002123 default:
2124 break;
2125 }
2126
2127 UNREACHABLE();
2128 return 0;
2129}
2130
2131
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002132void String::Set(int index, uint16_t value) {
2133 ASSERT(index >= 0 && index < length());
2134 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002135
ager@chromium.org5ec48922009-05-05 07:25:34 +00002136 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002137 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2138 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002139}
2140
2141
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002142bool String::IsFlat() {
2143 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002144 case kConsStringTag: {
2145 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002146 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00002147 return second->length() == 0;
2148 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002149 default:
2150 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002151 }
2152}
2153
2154
ager@chromium.org7c537e22008-10-16 08:43:32 +00002155uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002156 ASSERT(index >= 0 && index < length());
2157 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2158}
2159
2160
ager@chromium.org7c537e22008-10-16 08:43:32 +00002161void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002162 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2163 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2164 static_cast<byte>(value));
2165}
2166
2167
ager@chromium.org7c537e22008-10-16 08:43:32 +00002168Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002169 return FIELD_ADDR(this, kHeaderSize);
2170}
2171
2172
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002173char* SeqAsciiString::GetChars() {
2174 return reinterpret_cast<char*>(GetCharsAddress());
2175}
2176
2177
ager@chromium.org7c537e22008-10-16 08:43:32 +00002178Address SeqTwoByteString::GetCharsAddress() {
2179 return FIELD_ADDR(this, kHeaderSize);
2180}
2181
2182
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002183uc16* SeqTwoByteString::GetChars() {
2184 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2185}
2186
2187
ager@chromium.org7c537e22008-10-16 08:43:32 +00002188uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002189 ASSERT(index >= 0 && index < length());
2190 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2191}
2192
2193
ager@chromium.org7c537e22008-10-16 08:43:32 +00002194void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002195 ASSERT(index >= 0 && index < length());
2196 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2197}
2198
2199
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002200int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002201 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002202}
2203
2204
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002205int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002206 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002207}
2208
2209
ager@chromium.org870a0b62008-11-04 11:43:05 +00002210String* ConsString::first() {
2211 return String::cast(READ_FIELD(this, kFirstOffset));
2212}
2213
2214
2215Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002216 return READ_FIELD(this, kFirstOffset);
2217}
2218
2219
ager@chromium.org870a0b62008-11-04 11:43:05 +00002220void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002221 WRITE_FIELD(this, kFirstOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002222 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002223}
2224
2225
ager@chromium.org870a0b62008-11-04 11:43:05 +00002226String* ConsString::second() {
2227 return String::cast(READ_FIELD(this, kSecondOffset));
2228}
2229
2230
2231Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002232 return READ_FIELD(this, kSecondOffset);
2233}
2234
2235
ager@chromium.org870a0b62008-11-04 11:43:05 +00002236void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002237 WRITE_FIELD(this, kSecondOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002238 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002239}
2240
2241
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002242ExternalAsciiString::Resource* ExternalAsciiString::resource() {
2243 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2244}
2245
2246
2247void ExternalAsciiString::set_resource(
2248 ExternalAsciiString::Resource* resource) {
2249 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2250}
2251
2252
2253ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
2254 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2255}
2256
2257
2258void ExternalTwoByteString::set_resource(
2259 ExternalTwoByteString::Resource* resource) {
2260 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2261}
2262
2263
ager@chromium.orgac091b72010-05-05 07:34:42 +00002264void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002265 set_finger_index(kEntriesIndex);
2266 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002267}
2268
2269
2270void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002271 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002272 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002273 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002274 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002275 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002276 MakeZeroSize();
2277}
2278
2279
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002280int JSFunctionResultCache::size() {
2281 return Smi::cast(get(kCacheSizeIndex))->value();
2282}
2283
2284
2285void JSFunctionResultCache::set_size(int size) {
2286 set(kCacheSizeIndex, Smi::FromInt(size));
2287}
2288
2289
2290int JSFunctionResultCache::finger_index() {
2291 return Smi::cast(get(kFingerIndex))->value();
2292}
2293
2294
2295void JSFunctionResultCache::set_finger_index(int finger_index) {
2296 set(kFingerIndex, Smi::FromInt(finger_index));
2297}
2298
2299
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002300byte ByteArray::get(int index) {
2301 ASSERT(index >= 0 && index < this->length());
2302 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2303}
2304
2305
2306void ByteArray::set(int index, byte value) {
2307 ASSERT(index >= 0 && index < this->length());
2308 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2309}
2310
2311
2312int ByteArray::get_int(int index) {
2313 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2314 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2315}
2316
2317
2318ByteArray* ByteArray::FromDataStartAddress(Address address) {
2319 ASSERT_TAG_ALIGNED(address);
2320 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2321}
2322
2323
2324Address ByteArray::GetDataStartAddress() {
2325 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2326}
2327
2328
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002329uint8_t* ExternalPixelArray::external_pixel_pointer() {
2330 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002331}
2332
2333
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002334uint8_t ExternalPixelArray::get(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002335 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002336 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002337 return ptr[index];
2338}
2339
2340
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002341void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002342 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002343 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002344 ptr[index] = value;
2345}
2346
2347
ager@chromium.org3811b432009-10-28 14:53:37 +00002348void* ExternalArray::external_pointer() {
2349 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2350 return reinterpret_cast<void*>(ptr);
2351}
2352
2353
2354void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2355 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2356 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2357}
2358
2359
2360int8_t ExternalByteArray::get(int index) {
2361 ASSERT((index >= 0) && (index < this->length()));
2362 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2363 return ptr[index];
2364}
2365
2366
2367void ExternalByteArray::set(int index, int8_t value) {
2368 ASSERT((index >= 0) && (index < this->length()));
2369 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2370 ptr[index] = value;
2371}
2372
2373
2374uint8_t ExternalUnsignedByteArray::get(int index) {
2375 ASSERT((index >= 0) && (index < this->length()));
2376 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2377 return ptr[index];
2378}
2379
2380
2381void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2382 ASSERT((index >= 0) && (index < this->length()));
2383 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2384 ptr[index] = value;
2385}
2386
2387
2388int16_t ExternalShortArray::get(int index) {
2389 ASSERT((index >= 0) && (index < this->length()));
2390 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2391 return ptr[index];
2392}
2393
2394
2395void ExternalShortArray::set(int index, int16_t value) {
2396 ASSERT((index >= 0) && (index < this->length()));
2397 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2398 ptr[index] = value;
2399}
2400
2401
2402uint16_t ExternalUnsignedShortArray::get(int index) {
2403 ASSERT((index >= 0) && (index < this->length()));
2404 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2405 return ptr[index];
2406}
2407
2408
2409void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2410 ASSERT((index >= 0) && (index < this->length()));
2411 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2412 ptr[index] = value;
2413}
2414
2415
2416int32_t ExternalIntArray::get(int index) {
2417 ASSERT((index >= 0) && (index < this->length()));
2418 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2419 return ptr[index];
2420}
2421
2422
2423void ExternalIntArray::set(int index, int32_t value) {
2424 ASSERT((index >= 0) && (index < this->length()));
2425 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2426 ptr[index] = value;
2427}
2428
2429
2430uint32_t ExternalUnsignedIntArray::get(int index) {
2431 ASSERT((index >= 0) && (index < this->length()));
2432 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2433 return ptr[index];
2434}
2435
2436
2437void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2438 ASSERT((index >= 0) && (index < this->length()));
2439 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2440 ptr[index] = value;
2441}
2442
2443
2444float ExternalFloatArray::get(int index) {
2445 ASSERT((index >= 0) && (index < this->length()));
2446 float* ptr = static_cast<float*>(external_pointer());
2447 return ptr[index];
2448}
2449
2450
2451void ExternalFloatArray::set(int index, float value) {
2452 ASSERT((index >= 0) && (index < this->length()));
2453 float* ptr = static_cast<float*>(external_pointer());
2454 ptr[index] = value;
2455}
2456
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002457
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002458double ExternalDoubleArray::get(int index) {
2459 ASSERT((index >= 0) && (index < this->length()));
2460 double* ptr = static_cast<double*>(external_pointer());
2461 return ptr[index];
2462}
2463
2464
2465void ExternalDoubleArray::set(int index, double value) {
2466 ASSERT((index >= 0) && (index < this->length()));
2467 double* ptr = static_cast<double*>(external_pointer());
2468 ptr[index] = value;
2469}
2470
2471
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002472int Map::visitor_id() {
2473 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2474}
2475
2476
2477void Map::set_visitor_id(int id) {
2478 ASSERT(0 <= id && id < 256);
2479 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2480}
2481
ager@chromium.org3811b432009-10-28 14:53:37 +00002482
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002483int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002484 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2485}
2486
2487
2488int Map::inobject_properties() {
2489 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002490}
2491
2492
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002493int Map::pre_allocated_property_fields() {
2494 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2495}
2496
2497
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002498int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002499 int instance_size = map->instance_size();
2500 if (instance_size != kVariableSizeSentinel) return instance_size;
2501 // We can ignore the "symbol" bit becase it is only set for symbols
2502 // and implies a string type.
2503 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002504 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002505 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002506 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002507 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002508 if (instance_type == ASCII_STRING_TYPE) {
2509 return SeqAsciiString::SizeFor(
2510 reinterpret_cast<SeqAsciiString*>(this)->length());
2511 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002512 if (instance_type == BYTE_ARRAY_TYPE) {
2513 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2514 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002515 if (instance_type == STRING_TYPE) {
2516 return SeqTwoByteString::SizeFor(
2517 reinterpret_cast<SeqTwoByteString*>(this)->length());
2518 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002519 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2520 return FixedDoubleArray::SizeFor(
2521 reinterpret_cast<FixedDoubleArray*>(this)->length());
2522 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002523 ASSERT(instance_type == CODE_TYPE);
2524 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002525}
2526
2527
2528void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002529 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002530 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002531 ASSERT(0 <= value && value < 256);
2532 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2533}
2534
2535
ager@chromium.org7c537e22008-10-16 08:43:32 +00002536void Map::set_inobject_properties(int value) {
2537 ASSERT(0 <= value && value < 256);
2538 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2539}
2540
2541
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002542void Map::set_pre_allocated_property_fields(int value) {
2543 ASSERT(0 <= value && value < 256);
2544 WRITE_BYTE_FIELD(this,
2545 kPreAllocatedPropertyFieldsOffset,
2546 static_cast<byte>(value));
2547}
2548
2549
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002550InstanceType Map::instance_type() {
2551 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2552}
2553
2554
2555void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002556 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2557}
2558
2559
2560int Map::unused_property_fields() {
2561 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2562}
2563
2564
2565void Map::set_unused_property_fields(int value) {
2566 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2567}
2568
2569
2570byte Map::bit_field() {
2571 return READ_BYTE_FIELD(this, kBitFieldOffset);
2572}
2573
2574
2575void Map::set_bit_field(byte value) {
2576 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2577}
2578
2579
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002580byte Map::bit_field2() {
2581 return READ_BYTE_FIELD(this, kBitField2Offset);
2582}
2583
2584
2585void Map::set_bit_field2(byte value) {
2586 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2587}
2588
2589
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002590void Map::set_non_instance_prototype(bool value) {
2591 if (value) {
2592 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2593 } else {
2594 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2595 }
2596}
2597
2598
2599bool Map::has_non_instance_prototype() {
2600 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2601}
2602
2603
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002604void Map::set_function_with_prototype(bool value) {
2605 if (value) {
2606 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2607 } else {
2608 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2609 }
2610}
2611
2612
2613bool Map::function_with_prototype() {
2614 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2615}
2616
2617
ager@chromium.org870a0b62008-11-04 11:43:05 +00002618void Map::set_is_access_check_needed(bool access_check_needed) {
2619 if (access_check_needed) {
2620 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2621 } else {
2622 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2623 }
2624}
2625
2626
2627bool Map::is_access_check_needed() {
2628 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2629}
2630
2631
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002632void Map::set_is_extensible(bool value) {
2633 if (value) {
2634 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2635 } else {
2636 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2637 }
2638}
2639
2640bool Map::is_extensible() {
2641 return ((1 << kIsExtensible) & bit_field2()) != 0;
2642}
2643
2644
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002645void Map::set_attached_to_shared_function_info(bool value) {
2646 if (value) {
2647 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2648 } else {
2649 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2650 }
2651}
2652
2653bool Map::attached_to_shared_function_info() {
2654 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2655}
2656
2657
2658void Map::set_is_shared(bool value) {
2659 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002660 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002661 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002662 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002663 }
2664}
2665
2666bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002667 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002668}
2669
2670
2671JSFunction* Map::unchecked_constructor() {
2672 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2673}
2674
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002675
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002676FixedArray* Map::unchecked_prototype_transitions() {
2677 return reinterpret_cast<FixedArray*>(
2678 READ_FIELD(this, kPrototypeTransitionsOffset));
2679}
2680
2681
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002682Code::Flags Code::flags() {
2683 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2684}
2685
2686
2687void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002688 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002689 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002690 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2691 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002692 ExtractArgumentsCountFromFlags(flags) >= 0);
2693 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2694}
2695
2696
2697Code::Kind Code::kind() {
2698 return ExtractKindFromFlags(flags());
2699}
2700
2701
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002702InLoopFlag Code::ic_in_loop() {
2703 return ExtractICInLoopFromFlags(flags());
2704}
2705
2706
kasper.lund7276f142008-07-30 08:49:36 +00002707InlineCacheState Code::ic_state() {
2708 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002709 // Only allow uninitialized or debugger states for non-IC code
2710 // objects. This is used in the debugger to determine whether or not
2711 // a call to code object has been replaced with a debug break call.
2712 ASSERT(is_inline_cache_stub() ||
2713 result == UNINITIALIZED ||
2714 result == DEBUG_BREAK ||
2715 result == DEBUG_PREPARE_STEP_IN);
2716 return result;
2717}
2718
2719
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002720Code::ExtraICState Code::extra_ic_state() {
2721 ASSERT(is_inline_cache_stub());
2722 return ExtractExtraICStateFromFlags(flags());
2723}
2724
2725
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002726PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002727 return ExtractTypeFromFlags(flags());
2728}
2729
2730
2731int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002732 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002733 return ExtractArgumentsCountFromFlags(flags());
2734}
2735
2736
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002737int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002738 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002739 kind() == UNARY_OP_IC ||
2740 kind() == BINARY_OP_IC ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002741 kind() == COMPARE_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002742 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002743}
2744
2745
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002746void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002747 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002748 kind() == UNARY_OP_IC ||
2749 kind() == BINARY_OP_IC ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002750 kind() == COMPARE_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002751 ASSERT(0 <= major && major < 256);
2752 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002753}
2754
2755
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002756bool Code::optimizable() {
2757 ASSERT(kind() == FUNCTION);
2758 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2759}
2760
2761
2762void Code::set_optimizable(bool value) {
2763 ASSERT(kind() == FUNCTION);
2764 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2765}
2766
2767
2768bool Code::has_deoptimization_support() {
2769 ASSERT(kind() == FUNCTION);
2770 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2771}
2772
2773
2774void Code::set_has_deoptimization_support(bool value) {
2775 ASSERT(kind() == FUNCTION);
2776 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2777}
2778
2779
2780int Code::allow_osr_at_loop_nesting_level() {
2781 ASSERT(kind() == FUNCTION);
2782 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2783}
2784
2785
2786void Code::set_allow_osr_at_loop_nesting_level(int level) {
2787 ASSERT(kind() == FUNCTION);
2788 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2789 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2790}
2791
2792
2793unsigned Code::stack_slots() {
2794 ASSERT(kind() == OPTIMIZED_FUNCTION);
2795 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2796}
2797
2798
2799void Code::set_stack_slots(unsigned slots) {
2800 ASSERT(kind() == OPTIMIZED_FUNCTION);
2801 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2802}
2803
2804
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002805unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002806 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002807 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002808}
2809
2810
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002811void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002812 ASSERT(kind() == OPTIMIZED_FUNCTION);
2813 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002814 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002815}
2816
2817
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002818unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002819 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002820 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002821}
2822
2823
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002824void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002825 ASSERT(kind() == FUNCTION);
2826 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002827 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002828}
2829
2830
2831CheckType Code::check_type() {
2832 ASSERT(is_call_stub() || is_keyed_call_stub());
2833 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2834 return static_cast<CheckType>(type);
2835}
2836
2837
2838void Code::set_check_type(CheckType value) {
2839 ASSERT(is_call_stub() || is_keyed_call_stub());
2840 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2841}
2842
2843
danno@chromium.org40cb8782011-05-25 07:58:50 +00002844byte Code::unary_op_type() {
2845 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002846 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
2847}
2848
2849
danno@chromium.org40cb8782011-05-25 07:58:50 +00002850void Code::set_unary_op_type(byte value) {
2851 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002852 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
2853}
2854
2855
danno@chromium.org40cb8782011-05-25 07:58:50 +00002856byte Code::binary_op_type() {
2857 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002858 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2859}
2860
2861
danno@chromium.org40cb8782011-05-25 07:58:50 +00002862void Code::set_binary_op_type(byte value) {
2863 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002864 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2865}
2866
2867
danno@chromium.org40cb8782011-05-25 07:58:50 +00002868byte Code::binary_op_result_type() {
2869 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002870 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2871}
2872
2873
danno@chromium.org40cb8782011-05-25 07:58:50 +00002874void Code::set_binary_op_result_type(byte value) {
2875 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002876 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2877}
2878
2879
2880byte Code::compare_state() {
2881 ASSERT(is_compare_ic_stub());
2882 return READ_BYTE_FIELD(this, kCompareStateOffset);
2883}
2884
2885
2886void Code::set_compare_state(byte value) {
2887 ASSERT(is_compare_ic_stub());
2888 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2889}
2890
2891
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002892bool Code::is_inline_cache_stub() {
2893 Kind kind = this->kind();
2894 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2895}
2896
2897
2898Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002899 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002900 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002901 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002902 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002903 int argc,
2904 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002905 // Extra IC state is only allowed for call IC stubs or for store IC
2906 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002907 ASSERT(extra_ic_state == kNoExtraICState ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002908 (kind == CALL_IC) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00002909 (kind == STORE_IC) ||
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002910 (kind == KEYED_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002911 // Compute the bit mask.
2912 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002913 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002914 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002915 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002916 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002917 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002918 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002919 // Cast to flags and validate result before returning it.
2920 Flags result = static_cast<Flags>(bits);
2921 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002922 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002923 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002924 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002925 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002926 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2927 return result;
2928}
2929
2930
2931Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2932 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002933 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002934 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002935 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002936 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002937 return ComputeFlags(
2938 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002939}
2940
2941
2942Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2943 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2944 return static_cast<Kind>(bits);
2945}
2946
2947
kasper.lund7276f142008-07-30 08:49:36 +00002948InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2949 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002950 return static_cast<InlineCacheState>(bits);
2951}
2952
2953
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002954Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
2955 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
2956 return static_cast<ExtraICState>(bits);
2957}
2958
2959
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002960InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2961 int bits = (flags & kFlagsICInLoopMask);
2962 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2963}
2964
2965
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002966PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2967 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2968 return static_cast<PropertyType>(bits);
2969}
2970
2971
2972int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2973 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2974}
2975
2976
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002977InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2978 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2979 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2980}
2981
2982
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002983Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2984 int bits = flags & ~kFlagsTypeMask;
2985 return static_cast<Flags>(bits);
2986}
2987
2988
ager@chromium.org8bb60582008-12-11 12:02:20 +00002989Code* Code::GetCodeFromTargetAddress(Address address) {
2990 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2991 // GetCodeFromTargetAddress might be called when marking objects during mark
2992 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2993 // Code::cast. Code::cast does not work when the object's map is
2994 // marked.
2995 Code* result = reinterpret_cast<Code*>(code);
2996 return result;
2997}
2998
2999
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003000Isolate* Map::isolate() {
3001 return heap()->isolate();
3002}
3003
3004
3005Heap* Map::heap() {
3006 // NOTE: address() helper is not used to save one instruction.
3007 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3008 ASSERT(heap != NULL);
3009 ASSERT(heap->isolate() == Isolate::Current());
3010 return heap;
3011}
3012
3013
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003014Heap* Code::heap() {
3015 // NOTE: address() helper is not used to save one instruction.
3016 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3017 ASSERT(heap != NULL);
3018 ASSERT(heap->isolate() == Isolate::Current());
3019 return heap;
3020}
3021
3022
3023Isolate* Code::isolate() {
3024 return heap()->isolate();
3025}
3026
3027
3028Heap* JSGlobalPropertyCell::heap() {
3029 // NOTE: address() helper is not used to save one instruction.
3030 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3031 ASSERT(heap != NULL);
3032 ASSERT(heap->isolate() == Isolate::Current());
3033 return heap;
3034}
3035
3036
3037Isolate* JSGlobalPropertyCell::isolate() {
3038 return heap()->isolate();
3039}
3040
3041
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003042Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3043 return HeapObject::
3044 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3045}
3046
3047
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003048Object* Map::prototype() {
3049 return READ_FIELD(this, kPrototypeOffset);
3050}
3051
3052
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003053void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003054 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003055 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003056 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003057}
3058
3059
lrn@chromium.org303ada72010-10-27 09:33:13 +00003060MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003061 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003062 Object* obj;
3063 { MaybeObject* maybe_obj = CopyDropTransitions();
3064 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3065 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003066 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003067 new_map->set_elements_kind(JSObject::FAST_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003068 isolate()->counters()->map_to_fast_elements()->Increment();
3069 return new_map;
3070}
3071
3072
3073MaybeObject* Map::GetFastDoubleElementsMap() {
3074 if (has_fast_double_elements()) return this;
3075 Object* obj;
3076 { MaybeObject* maybe_obj = CopyDropTransitions();
3077 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3078 }
3079 Map* new_map = Map::cast(obj);
3080 new_map->set_elements_kind(JSObject::FAST_DOUBLE_ELEMENTS);
3081 isolate()->counters()->map_to_fast_double_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003082 return new_map;
3083}
3084
3085
lrn@chromium.org303ada72010-10-27 09:33:13 +00003086MaybeObject* Map::GetSlowElementsMap() {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003087 if (!has_fast_elements() && !has_fast_double_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003088 Object* obj;
3089 { MaybeObject* maybe_obj = CopyDropTransitions();
3090 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3091 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003092 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003093 new_map->set_elements_kind(JSObject::DICTIONARY_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003094 isolate()->counters()->map_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003095 return new_map;
3096}
3097
3098
danno@chromium.org40cb8782011-05-25 07:58:50 +00003099DescriptorArray* Map::instance_descriptors() {
3100 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3101 if (object->IsSmi()) {
3102 return HEAP->empty_descriptor_array();
3103 } else {
3104 return DescriptorArray::cast(object);
3105 }
3106}
3107
3108
3109void Map::init_instance_descriptors() {
3110 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3111}
3112
3113
3114void Map::clear_instance_descriptors() {
3115 Object* object = READ_FIELD(this,
3116 kInstanceDescriptorsOrBitField3Offset);
3117 if (!object->IsSmi()) {
3118 WRITE_FIELD(
3119 this,
3120 kInstanceDescriptorsOrBitField3Offset,
3121 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3122 }
3123}
3124
3125
3126void Map::set_instance_descriptors(DescriptorArray* value,
3127 WriteBarrierMode mode) {
3128 Object* object = READ_FIELD(this,
3129 kInstanceDescriptorsOrBitField3Offset);
3130 if (value == isolate()->heap()->empty_descriptor_array()) {
3131 clear_instance_descriptors();
3132 return;
3133 } else {
3134 if (object->IsSmi()) {
3135 value->set_bit_field3_storage(Smi::cast(object)->value());
3136 } else {
3137 value->set_bit_field3_storage(
3138 DescriptorArray::cast(object)->bit_field3_storage());
3139 }
3140 }
3141 ASSERT(!is_shared());
3142 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
3143 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3144 this,
3145 kInstanceDescriptorsOrBitField3Offset,
3146 mode);
3147}
3148
3149
3150int Map::bit_field3() {
3151 Object* object = READ_FIELD(this,
3152 kInstanceDescriptorsOrBitField3Offset);
3153 if (object->IsSmi()) {
3154 return Smi::cast(object)->value();
3155 } else {
3156 return DescriptorArray::cast(object)->bit_field3_storage();
3157 }
3158}
3159
3160
3161void Map::set_bit_field3(int value) {
3162 ASSERT(Smi::IsValid(value));
3163 Object* object = READ_FIELD(this,
3164 kInstanceDescriptorsOrBitField3Offset);
3165 if (object->IsSmi()) {
3166 WRITE_FIELD(this,
3167 kInstanceDescriptorsOrBitField3Offset,
3168 Smi::FromInt(value));
3169 } else {
3170 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3171 }
3172}
3173
3174
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003175ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003176ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003177ACCESSORS(Map, constructor, Object, kConstructorOffset)
3178
3179ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
3180ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003181ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
3182 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003183
3184ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3185ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003186ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003187
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003188ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003189
3190ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3191ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3192ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3193ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3194ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3195
3196ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3197ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3198ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3199
3200ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3201ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3202ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3203ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3204ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3205ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3206
3207ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3208ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3209
3210ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3211ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3212
3213ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3214ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003215ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3216 kPropertyAccessorsOffset)
3217ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3218 kPrototypeTemplateOffset)
3219ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3220ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3221 kNamedPropertyHandlerOffset)
3222ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3223 kIndexedPropertyHandlerOffset)
3224ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3225 kInstanceTemplateOffset)
3226ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3227ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003228ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3229 kInstanceCallHandlerOffset)
3230ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3231 kAccessCheckInfoOffset)
3232ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3233
3234ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003235ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3236 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003237
3238ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3239ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3240
3241ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3242
3243ACCESSORS(Script, source, Object, kSourceOffset)
3244ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003245ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003246ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3247ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003248ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003249ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003250ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003251ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003252ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003253ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003254ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003255ACCESSORS(Script, eval_from_instructions_offset, Smi,
3256 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003257
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003258#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003259ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3260ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3261ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3262ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3263
3264ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3265ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3266ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3267ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003268#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003269
3270ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003271ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3272ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003273ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3274 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003275ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003276ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3277ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003278ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003279ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3280 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003281
3282BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3283 kHiddenPrototypeBit)
3284BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3285BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3286 kNeedsAccessCheckBit)
3287BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3288 kIsExpressionBit)
3289BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3290 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003291BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003292 has_only_simple_this_property_assignments,
3293 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003294BOOL_ACCESSORS(SharedFunctionInfo,
3295 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003296 allows_lazy_compilation,
3297 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003298
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003299
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003300#if V8_HOST_ARCH_32_BIT
3301SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3302SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003303 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003304SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003305 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003306SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3307SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003308 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003309SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3310SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003311 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003312SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003313 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003314SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003315 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003316SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003317#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003318
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003319#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003320 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003321 int holder::name() { \
3322 int value = READ_INT_FIELD(this, offset); \
3323 ASSERT(kHeapObjectTag == 1); \
3324 ASSERT((value & kHeapObjectTag) == 0); \
3325 return value >> 1; \
3326 } \
3327 void holder::set_##name(int value) { \
3328 ASSERT(kHeapObjectTag == 1); \
3329 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3330 (value & 0xC0000000) == 0x000000000); \
3331 WRITE_INT_FIELD(this, \
3332 offset, \
3333 (value << 1) & ~kHeapObjectTag); \
3334 }
3335
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003336#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3337 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003338 INT_ACCESSORS(holder, name, offset)
3339
3340
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003341PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003342PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3343 formal_parameter_count,
3344 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003345
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003346PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3347 expected_nof_properties,
3348 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003349PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3350
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003351PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3352PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3353 start_position_and_type,
3354 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003355
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003356PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3357 function_token_position,
3358 kFunctionTokenPositionOffset)
3359PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3360 compiler_hints,
3361 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003362
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003363PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3364 this_property_assignments_count,
3365 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003366PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003367#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003368
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003369
3370int SharedFunctionInfo::construction_count() {
3371 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3372}
3373
3374
3375void SharedFunctionInfo::set_construction_count(int value) {
3376 ASSERT(0 <= value && value < 256);
3377 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3378}
3379
3380
3381bool SharedFunctionInfo::live_objects_may_exist() {
3382 return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
3383}
3384
3385
3386void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
3387 if (value) {
3388 set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
3389 } else {
3390 set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
3391 }
3392}
3393
3394
3395bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003396 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003397}
3398
3399
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003400bool SharedFunctionInfo::optimization_disabled() {
3401 return BooleanBit::get(compiler_hints(), kOptimizationDisabled);
3402}
3403
3404
3405void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3406 set_compiler_hints(BooleanBit::set(compiler_hints(),
3407 kOptimizationDisabled,
3408 disable));
3409 // If disabling optimizations we reflect that in the code object so
3410 // it will not be counted as optimizable code.
3411 if ((code()->kind() == Code::FUNCTION) && disable) {
3412 code()->set_optimizable(false);
3413 }
3414}
3415
3416
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003417bool SharedFunctionInfo::strict_mode() {
3418 return BooleanBit::get(compiler_hints(), kStrictModeFunction);
3419}
3420
3421
3422void SharedFunctionInfo::set_strict_mode(bool value) {
3423 set_compiler_hints(BooleanBit::set(compiler_hints(),
3424 kStrictModeFunction,
3425 value));
3426}
3427
3428
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003429bool SharedFunctionInfo::native() {
3430 return BooleanBit::get(compiler_hints(), kNative);
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003431}
3432
3433
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003434void SharedFunctionInfo::set_native(bool value) {
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003435 set_compiler_hints(BooleanBit::set(compiler_hints(),
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003436 kNative,
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003437 value));
3438}
3439
3440
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003441ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3442ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3443
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003444ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3445
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003446bool Script::HasValidSource() {
3447 Object* src = this->source();
3448 if (!src->IsString()) return true;
3449 String* src_str = String::cast(src);
3450 if (!StringShape(src_str).IsExternal()) return true;
3451 if (src_str->IsAsciiRepresentation()) {
3452 return ExternalAsciiString::cast(src)->resource() != NULL;
3453 } else if (src_str->IsTwoByteRepresentation()) {
3454 return ExternalTwoByteString::cast(src)->resource() != NULL;
3455 }
3456 return true;
3457}
3458
3459
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003460void SharedFunctionInfo::DontAdaptArguments() {
3461 ASSERT(code()->kind() == Code::BUILTIN);
3462 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3463}
3464
3465
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003466int SharedFunctionInfo::start_position() {
3467 return start_position_and_type() >> kStartPositionShift;
3468}
3469
3470
3471void SharedFunctionInfo::set_start_position(int start_position) {
3472 set_start_position_and_type((start_position << kStartPositionShift)
3473 | (start_position_and_type() & ~kStartPositionMask));
3474}
3475
3476
3477Code* SharedFunctionInfo::code() {
3478 return Code::cast(READ_FIELD(this, kCodeOffset));
3479}
3480
3481
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003482Code* SharedFunctionInfo::unchecked_code() {
3483 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3484}
3485
3486
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003487void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003488 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003489 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003490}
3491
3492
ager@chromium.orgb5737492010-07-15 09:29:43 +00003493SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3494 return reinterpret_cast<SerializedScopeInfo*>(
3495 READ_FIELD(this, kScopeInfoOffset));
3496}
3497
3498
3499void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3500 WriteBarrierMode mode) {
3501 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003502 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003503}
3504
3505
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003506Smi* SharedFunctionInfo::deopt_counter() {
3507 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3508}
3509
3510
3511void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3512 WRITE_FIELD(this, kDeoptCounterOffset, value);
3513}
3514
3515
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003516bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003517 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003518 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003519}
3520
3521
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003522bool SharedFunctionInfo::IsApiFunction() {
3523 return function_data()->IsFunctionTemplateInfo();
3524}
3525
3526
3527FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3528 ASSERT(IsApiFunction());
3529 return FunctionTemplateInfo::cast(function_data());
3530}
3531
3532
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003533bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003534 return function_data()->IsSmi();
3535}
3536
3537
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003538BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3539 ASSERT(HasBuiltinFunctionId());
3540 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003541}
3542
3543
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003544int SharedFunctionInfo::code_age() {
3545 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3546}
3547
3548
3549void SharedFunctionInfo::set_code_age(int code_age) {
3550 set_compiler_hints(compiler_hints() |
3551 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3552}
3553
3554
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003555bool SharedFunctionInfo::has_deoptimization_support() {
3556 Code* code = this->code();
3557 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3558}
3559
3560
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003561bool JSFunction::IsBuiltin() {
3562 return context()->global()->IsJSBuiltinsObject();
3563}
3564
3565
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003566bool JSFunction::NeedsArgumentsAdaption() {
3567 return shared()->formal_parameter_count() !=
3568 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3569}
3570
3571
3572bool JSFunction::IsOptimized() {
3573 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3574}
3575
3576
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003577bool JSFunction::IsOptimizable() {
3578 return code()->kind() == Code::FUNCTION && code()->optimizable();
3579}
3580
3581
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003582bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003583 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003584}
3585
3586
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003587Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003588 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003589}
3590
3591
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003592Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003593 return reinterpret_cast<Code*>(
3594 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003595}
3596
3597
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003598void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003599 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003600 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003601 Address entry = value->entry();
3602 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003603}
3604
3605
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003606void JSFunction::ReplaceCode(Code* code) {
3607 bool was_optimized = IsOptimized();
3608 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3609
3610 set_code(code);
3611
3612 // Add/remove the function from the list of optimized functions for this
3613 // context based on the state change.
3614 if (!was_optimized && is_optimized) {
3615 context()->global_context()->AddOptimizedFunction(this);
3616 }
3617 if (was_optimized && !is_optimized) {
3618 context()->global_context()->RemoveOptimizedFunction(this);
3619 }
3620}
3621
3622
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003623Context* JSFunction::context() {
3624 return Context::cast(READ_FIELD(this, kContextOffset));
3625}
3626
3627
3628Object* JSFunction::unchecked_context() {
3629 return READ_FIELD(this, kContextOffset);
3630}
3631
3632
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003633SharedFunctionInfo* JSFunction::unchecked_shared() {
3634 return reinterpret_cast<SharedFunctionInfo*>(
3635 READ_FIELD(this, kSharedFunctionInfoOffset));
3636}
3637
3638
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003639void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003640 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003641 WRITE_FIELD(this, kContextOffset, value);
3642 WRITE_BARRIER(this, kContextOffset);
3643}
3644
3645ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3646 kPrototypeOrInitialMapOffset)
3647
3648
3649Map* JSFunction::initial_map() {
3650 return Map::cast(prototype_or_initial_map());
3651}
3652
3653
3654void JSFunction::set_initial_map(Map* value) {
3655 set_prototype_or_initial_map(value);
3656}
3657
3658
3659bool JSFunction::has_initial_map() {
3660 return prototype_or_initial_map()->IsMap();
3661}
3662
3663
3664bool JSFunction::has_instance_prototype() {
3665 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3666}
3667
3668
3669bool JSFunction::has_prototype() {
3670 return map()->has_non_instance_prototype() || has_instance_prototype();
3671}
3672
3673
3674Object* JSFunction::instance_prototype() {
3675 ASSERT(has_instance_prototype());
3676 if (has_initial_map()) return initial_map()->prototype();
3677 // When there is no initial map and the prototype is a JSObject, the
3678 // initial map field is used for the prototype field.
3679 return prototype_or_initial_map();
3680}
3681
3682
3683Object* JSFunction::prototype() {
3684 ASSERT(has_prototype());
3685 // If the function's prototype property has been set to a non-JSObject
3686 // value, that value is stored in the constructor field of the map.
3687 if (map()->has_non_instance_prototype()) return map()->constructor();
3688 return instance_prototype();
3689}
3690
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003691bool JSFunction::should_have_prototype() {
3692 return map()->function_with_prototype();
3693}
3694
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003695
3696bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003697 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003698}
3699
3700
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003701int JSFunction::NumberOfLiterals() {
3702 return literals()->length();
3703}
3704
3705
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003706Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003707 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003708 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003709}
3710
3711
3712void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3713 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003714 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003715 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3716 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3717}
3718
3719
3720Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003721 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003722 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3723}
3724
3725
3726void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3727 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003728 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003729 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003730 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003731}
3732
3733
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003734ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
3735
3736
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003737Address Foreign::address() {
3738 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003739}
3740
3741
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003742void Foreign::set_address(Address value) {
3743 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003744}
3745
3746
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003747ACCESSORS(JSValue, value, Object, kValueOffset)
3748
3749
3750JSValue* JSValue::cast(Object* obj) {
3751 ASSERT(obj->IsJSValue());
3752 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3753 return reinterpret_cast<JSValue*>(obj);
3754}
3755
3756
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003757ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3758ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3759ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3760ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3761ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3762SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3763SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3764
3765
3766JSMessageObject* JSMessageObject::cast(Object* obj) {
3767 ASSERT(obj->IsJSMessageObject());
3768 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3769 return reinterpret_cast<JSMessageObject*>(obj);
3770}
3771
3772
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003773INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003774ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003775ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003776ACCESSORS(Code, next_code_flushing_candidate,
3777 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003778
3779
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003780byte* Code::instruction_start() {
3781 return FIELD_ADDR(this, kHeaderSize);
3782}
3783
3784
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003785byte* Code::instruction_end() {
3786 return instruction_start() + instruction_size();
3787}
3788
3789
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003790int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003791 return RoundUp(instruction_size(), kObjectAlignment);
3792}
3793
3794
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003795FixedArray* Code::unchecked_deoptimization_data() {
3796 return reinterpret_cast<FixedArray*>(
3797 READ_FIELD(this, kDeoptimizationDataOffset));
3798}
3799
3800
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003801ByteArray* Code::unchecked_relocation_info() {
3802 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003803}
3804
3805
3806byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003807 return unchecked_relocation_info()->GetDataStartAddress();
3808}
3809
3810
3811int Code::relocation_size() {
3812 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003813}
3814
3815
3816byte* Code::entry() {
3817 return instruction_start();
3818}
3819
3820
3821bool Code::contains(byte* pc) {
3822 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003823 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003824}
3825
3826
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003827ACCESSORS(JSArray, length, Object, kLengthOffset)
3828
3829
ager@chromium.org236ad962008-09-25 09:45:57 +00003830ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003831
3832
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003833JSRegExp::Type JSRegExp::TypeTag() {
3834 Object* data = this->data();
3835 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3836 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3837 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003838}
3839
3840
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003841int JSRegExp::CaptureCount() {
3842 switch (TypeTag()) {
3843 case ATOM:
3844 return 0;
3845 case IRREGEXP:
3846 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3847 default:
3848 UNREACHABLE();
3849 return -1;
3850 }
3851}
3852
3853
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003854JSRegExp::Flags JSRegExp::GetFlags() {
3855 ASSERT(this->data()->IsFixedArray());
3856 Object* data = this->data();
3857 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3858 return Flags(smi->value());
3859}
3860
3861
3862String* JSRegExp::Pattern() {
3863 ASSERT(this->data()->IsFixedArray());
3864 Object* data = this->data();
3865 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3866 return pattern;
3867}
3868
3869
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003870Object* JSRegExp::DataAt(int index) {
3871 ASSERT(TypeTag() != NOT_COMPILED);
3872 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003873}
3874
3875
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003876void JSRegExp::SetDataAt(int index, Object* value) {
3877 ASSERT(TypeTag() != NOT_COMPILED);
3878 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3879 FixedArray::cast(data())->set(index, value);
3880}
3881
3882
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003883JSObject::ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003884 ElementsKind kind = map()->elements_kind();
3885 ASSERT((kind == FAST_ELEMENTS &&
3886 (elements()->map() == GetHeap()->fixed_array_map() ||
3887 elements()->map() == GetHeap()->fixed_cow_array_map())) ||
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003888 (kind == FAST_DOUBLE_ELEMENTS &&
3889 elements()->IsFixedDoubleArray()) ||
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003890 (kind == DICTIONARY_ELEMENTS &&
3891 elements()->IsFixedArray() &&
3892 elements()->IsDictionary()) ||
3893 (kind > DICTIONARY_ELEMENTS));
3894 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003895}
3896
3897
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003898bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003899 return GetElementsKind() == FAST_ELEMENTS;
3900}
3901
3902
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003903bool JSObject::HasFastDoubleElements() {
3904 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
3905}
3906
3907
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003908bool JSObject::HasDictionaryElements() {
3909 return GetElementsKind() == DICTIONARY_ELEMENTS;
3910}
3911
3912
ager@chromium.org3811b432009-10-28 14:53:37 +00003913bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003914 HeapObject* array = elements();
3915 ASSERT(array != NULL);
3916 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00003917}
3918
3919
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003920#define EXTERNAL_ELEMENTS_CHECK(name, type) \
3921bool JSObject::HasExternal##name##Elements() { \
3922 HeapObject* array = elements(); \
3923 ASSERT(array != NULL); \
3924 if (!array->IsHeapObject()) \
3925 return false; \
3926 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00003927}
3928
3929
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003930EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
3931EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
3932EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
3933EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
3934 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
3935EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
3936EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
3937 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
3938EXTERNAL_ELEMENTS_CHECK(Float,
3939 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003940EXTERNAL_ELEMENTS_CHECK(Double,
3941 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003942EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00003943
3944
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003945bool JSObject::HasNamedInterceptor() {
3946 return map()->has_named_interceptor();
3947}
3948
3949
3950bool JSObject::HasIndexedInterceptor() {
3951 return map()->has_indexed_interceptor();
3952}
3953
3954
ager@chromium.org5c838252010-02-19 08:53:10 +00003955bool JSObject::AllowsSetElementsLength() {
3956 bool result = elements()->IsFixedArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003957 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00003958 return result;
3959}
3960
3961
lrn@chromium.org303ada72010-10-27 09:33:13 +00003962MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003963 ASSERT(HasFastElements());
3964 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003965 Isolate* isolate = GetIsolate();
3966 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003967 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003968 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
3969 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00003970 if (!maybe_writable_elems->ToObject(&writable_elems)) {
3971 return maybe_writable_elems;
3972 }
3973 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003974 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003975 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003976 return writable_elems;
3977}
3978
3979
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003980StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003981 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003982 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003983}
3984
3985
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003986NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003987 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003988 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003989}
3990
3991
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003992bool String::IsHashFieldComputed(uint32_t field) {
3993 return (field & kHashNotComputedMask) == 0;
3994}
3995
3996
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003997bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003998 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003999}
4000
4001
4002uint32_t String::Hash() {
4003 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004004 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004005 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004006 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004007 return ComputeAndSetHash();
4008}
4009
4010
ager@chromium.org7c537e22008-10-16 08:43:32 +00004011StringHasher::StringHasher(int length)
4012 : length_(length),
4013 raw_running_hash_(0),
4014 array_index_(0),
4015 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4016 is_first_char_(true),
4017 is_valid_(true) { }
4018
4019
4020bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004021 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004022}
4023
4024
4025void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004026 // Use the Jenkins one-at-a-time hash function to update the hash
4027 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004028 raw_running_hash_ += c;
4029 raw_running_hash_ += (raw_running_hash_ << 10);
4030 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004031 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004032 if (is_array_index_) {
4033 if (c < '0' || c > '9') {
4034 is_array_index_ = false;
4035 } else {
4036 int d = c - '0';
4037 if (is_first_char_) {
4038 is_first_char_ = false;
4039 if (c == '0' && length_ > 1) {
4040 is_array_index_ = false;
4041 return;
4042 }
4043 }
4044 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4045 is_array_index_ = false;
4046 } else {
4047 array_index_ = array_index_ * 10 + d;
4048 }
4049 }
4050 }
4051}
4052
4053
4054void StringHasher::AddCharacterNoIndex(uc32 c) {
4055 ASSERT(!is_array_index());
4056 raw_running_hash_ += c;
4057 raw_running_hash_ += (raw_running_hash_ << 10);
4058 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4059}
4060
4061
4062uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004063 // Get the calculated raw hash value and do some more bit ops to distribute
4064 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004065 uint32_t result = raw_running_hash_;
4066 result += (result << 3);
4067 result ^= (result >> 11);
4068 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004069 if (result == 0) {
4070 result = 27;
4071 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004072 return result;
4073}
4074
4075
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004076template <typename schar>
4077uint32_t HashSequentialString(const schar* chars, int length) {
4078 StringHasher hasher(length);
4079 if (!hasher.has_trivial_hash()) {
4080 int i;
4081 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4082 hasher.AddCharacter(chars[i]);
4083 }
4084 for (; i < length; i++) {
4085 hasher.AddCharacterNoIndex(chars[i]);
4086 }
4087 }
4088 return hasher.GetHashField();
4089}
4090
4091
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004092bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004093 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004094 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4095 return false;
4096 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004097 return SlowAsArrayIndex(index);
4098}
4099
4100
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004101Object* JSReceiver::GetPrototype() {
4102 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004103}
4104
4105
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004106PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004107 return GetPropertyAttributeWithReceiver(this, key);
4108}
4109
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004110// TODO(504): this may be useful in other places too where JSGlobalProxy
4111// is used.
4112Object* JSObject::BypassGlobalProxy() {
4113 if (IsJSGlobalProxy()) {
4114 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004115 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004116 ASSERT(proto->IsJSGlobalObject());
4117 return proto;
4118 }
4119 return this;
4120}
4121
4122
4123bool JSObject::HasHiddenPropertiesObject() {
4124 ASSERT(!IsJSGlobalProxy());
4125 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004126 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004127 false) != ABSENT;
4128}
4129
4130
4131Object* JSObject::GetHiddenPropertiesObject() {
4132 ASSERT(!IsJSGlobalProxy());
4133 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004134 // You can't install a getter on a property indexed by the hidden symbol,
4135 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
4136 // object.
4137 Object* result =
4138 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004139 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00004140 &attributes)->ToObjectUnchecked();
4141 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004142}
4143
4144
lrn@chromium.org303ada72010-10-27 09:33:13 +00004145MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004146 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004147 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004148 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00004149 DONT_ENUM,
4150 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004151}
4152
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004153
4154bool JSObject::HasElement(uint32_t index) {
4155 return HasElementWithReceiver(this, index);
4156}
4157
4158
4159bool AccessorInfo::all_can_read() {
4160 return BooleanBit::get(flag(), kAllCanReadBit);
4161}
4162
4163
4164void AccessorInfo::set_all_can_read(bool value) {
4165 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4166}
4167
4168
4169bool AccessorInfo::all_can_write() {
4170 return BooleanBit::get(flag(), kAllCanWriteBit);
4171}
4172
4173
4174void AccessorInfo::set_all_can_write(bool value) {
4175 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4176}
4177
4178
ager@chromium.org870a0b62008-11-04 11:43:05 +00004179bool AccessorInfo::prohibits_overwriting() {
4180 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4181}
4182
4183
4184void AccessorInfo::set_prohibits_overwriting(bool value) {
4185 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4186}
4187
4188
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004189PropertyAttributes AccessorInfo::property_attributes() {
4190 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4191}
4192
4193
4194void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
4195 ASSERT(AttributesField::is_valid(attributes));
4196 int rest_value = flag()->value() & ~AttributesField::mask();
4197 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
4198}
4199
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004200
4201template<typename Shape, typename Key>
4202void Dictionary<Shape, Key>::SetEntry(int entry,
4203 Object* key,
4204 Object* value) {
4205 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4206}
4207
4208
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004209template<typename Shape, typename Key>
4210void Dictionary<Shape, Key>::SetEntry(int entry,
4211 Object* key,
4212 Object* value,
4213 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004214 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004215 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004216 AssertNoAllocation no_gc;
4217 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004218 FixedArray::set(index, key, mode);
4219 FixedArray::set(index+1, value, mode);
4220 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004221}
4222
4223
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004224bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4225 ASSERT(other->IsNumber());
4226 return key == static_cast<uint32_t>(other->Number());
4227}
4228
4229
4230uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4231 return ComputeIntegerHash(key);
4232}
4233
4234
4235uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4236 ASSERT(other->IsNumber());
4237 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4238}
4239
4240
4241MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4242 return Isolate::Current()->heap()->NumberFromUint32(key);
4243}
4244
4245
4246bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4247 // We know that all entries in a hash table had their hash keys created.
4248 // Use that knowledge to have fast failure.
4249 if (key->Hash() != String::cast(other)->Hash()) return false;
4250 return key->Equals(String::cast(other));
4251}
4252
4253
4254uint32_t StringDictionaryShape::Hash(String* key) {
4255 return key->Hash();
4256}
4257
4258
4259uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4260 return String::cast(other)->Hash();
4261}
4262
4263
4264MaybeObject* StringDictionaryShape::AsObject(String* key) {
4265 return key;
4266}
4267
4268
4269void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004270 // No write barrier is needed since empty_fixed_array is not in new space.
4271 // Please note this function is used during marking:
4272 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004273 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4274 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004275}
4276
4277
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004278void JSArray::EnsureSize(int required_size) {
4279 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004280 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004281 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4282 if (elts->length() < required_size) {
4283 // Doubling in size would be overkill, but leave some slack to avoid
4284 // constantly growing.
4285 Expand(required_size + (required_size >> 3));
4286 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004287 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004288 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4289 // Expand will allocate a new backing store in new space even if the size
4290 // we asked for isn't larger than what we had before.
4291 Expand(required_size);
4292 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004293}
4294
4295
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004296void JSArray::set_length(Smi* length) {
4297 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4298}
4299
4300
ager@chromium.org7c537e22008-10-16 08:43:32 +00004301void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004302 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004303 set_elements(storage);
4304}
4305
4306
lrn@chromium.org303ada72010-10-27 09:33:13 +00004307MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004308 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004309 return GetHeap()->CopyFixedArray(this);
4310}
4311
4312
4313Relocatable::Relocatable(Isolate* isolate) {
4314 ASSERT(isolate == Isolate::Current());
4315 isolate_ = isolate;
4316 prev_ = isolate->relocatable_top();
4317 isolate->set_relocatable_top(this);
4318}
4319
4320
4321Relocatable::~Relocatable() {
4322 ASSERT(isolate_ == Isolate::Current());
4323 ASSERT_EQ(isolate_->relocatable_top(), this);
4324 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004325}
4326
4327
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004328int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4329 return map->instance_size();
4330}
4331
4332
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004333void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004334 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004335 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004336}
4337
4338
4339template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004340void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004341 StaticVisitor::VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004342 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004343}
4344
4345
4346void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4347 typedef v8::String::ExternalAsciiStringResource Resource;
4348 v->VisitExternalAsciiString(
4349 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4350}
4351
4352
4353template<typename StaticVisitor>
4354void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4355 typedef v8::String::ExternalAsciiStringResource Resource;
4356 StaticVisitor::VisitExternalAsciiString(
4357 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4358}
4359
4360
4361void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4362 typedef v8::String::ExternalStringResource Resource;
4363 v->VisitExternalTwoByteString(
4364 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4365}
4366
4367
4368template<typename StaticVisitor>
4369void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4370 typedef v8::String::ExternalStringResource Resource;
4371 StaticVisitor::VisitExternalTwoByteString(
4372 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4373}
4374
4375#define SLOT_ADDR(obj, offset) \
4376 reinterpret_cast<Object**>((obj)->address() + offset)
4377
4378template<int start_offset, int end_offset, int size>
4379void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4380 HeapObject* obj,
4381 ObjectVisitor* v) {
4382 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4383}
4384
4385
4386template<int start_offset>
4387void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4388 int object_size,
4389 ObjectVisitor* v) {
4390 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4391}
4392
4393#undef SLOT_ADDR
4394
4395
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004396#undef CAST_ACCESSOR
4397#undef INT_ACCESSORS
4398#undef SMI_ACCESSORS
4399#undef ACCESSORS
4400#undef FIELD_ADDR
4401#undef READ_FIELD
4402#undef WRITE_FIELD
4403#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004404#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004405#undef READ_MEMADDR_FIELD
4406#undef WRITE_MEMADDR_FIELD
4407#undef READ_DOUBLE_FIELD
4408#undef WRITE_DOUBLE_FIELD
4409#undef READ_INT_FIELD
4410#undef WRITE_INT_FIELD
4411#undef READ_SHORT_FIELD
4412#undef WRITE_SHORT_FIELD
4413#undef READ_BYTE_FIELD
4414#undef WRITE_BYTE_FIELD
4415
4416
4417} } // namespace v8::internal
4418
4419#endif // V8_OBJECTS_INL_H_