blob: 69d66cd1fa4c840bd99aad65eaf7b08bc7cedd93 [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() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000648 return IsHashTable() &&
649 this != 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
whesse@chromium.org7b260152011-06-20 15:33:18 +00002063// TODO(jkummerow): Investigate if it's possible to s/INT/SMI/ here (and
2064// subsequently unify H{Fixed,External}ArrayLength).
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002065INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002066
2067
ager@chromium.orgac091b72010-05-05 07:34:42 +00002068SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002069
2070
2071uint32_t String::hash_field() {
2072 return READ_UINT32_FIELD(this, kHashFieldOffset);
2073}
2074
2075
2076void String::set_hash_field(uint32_t value) {
2077 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002078#if V8_HOST_ARCH_64_BIT
2079 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2080#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002081}
2082
2083
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002084bool String::Equals(String* other) {
2085 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002086 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2087 return false;
2088 }
2089 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002090}
2091
2092
lrn@chromium.org303ada72010-10-27 09:33:13 +00002093MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002094 if (!StringShape(this).IsCons()) return this;
2095 ConsString* cons = ConsString::cast(this);
2096 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002097 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002098}
2099
2100
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002101String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002102 MaybeObject* flat = TryFlatten(pretenure);
2103 Object* successfully_flattened;
2104 if (flat->ToObject(&successfully_flattened)) {
2105 return String::cast(successfully_flattened);
2106 }
2107 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002108}
2109
2110
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002111uint16_t String::Get(int index) {
2112 ASSERT(index >= 0 && index < length());
2113 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002114 case kSeqStringTag | kAsciiStringTag:
2115 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2116 case kSeqStringTag | kTwoByteStringTag:
2117 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2118 case kConsStringTag | kAsciiStringTag:
2119 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002120 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002121 case kExternalStringTag | kAsciiStringTag:
2122 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2123 case kExternalStringTag | kTwoByteStringTag:
2124 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002125 default:
2126 break;
2127 }
2128
2129 UNREACHABLE();
2130 return 0;
2131}
2132
2133
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002134void String::Set(int index, uint16_t value) {
2135 ASSERT(index >= 0 && index < length());
2136 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002137
ager@chromium.org5ec48922009-05-05 07:25:34 +00002138 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002139 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2140 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002141}
2142
2143
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002144bool String::IsFlat() {
2145 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002146 case kConsStringTag: {
2147 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002148 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00002149 return second->length() == 0;
2150 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002151 default:
2152 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002153 }
2154}
2155
2156
ager@chromium.org7c537e22008-10-16 08:43:32 +00002157uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002158 ASSERT(index >= 0 && index < length());
2159 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2160}
2161
2162
ager@chromium.org7c537e22008-10-16 08:43:32 +00002163void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002164 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2165 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2166 static_cast<byte>(value));
2167}
2168
2169
ager@chromium.org7c537e22008-10-16 08:43:32 +00002170Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002171 return FIELD_ADDR(this, kHeaderSize);
2172}
2173
2174
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002175char* SeqAsciiString::GetChars() {
2176 return reinterpret_cast<char*>(GetCharsAddress());
2177}
2178
2179
ager@chromium.org7c537e22008-10-16 08:43:32 +00002180Address SeqTwoByteString::GetCharsAddress() {
2181 return FIELD_ADDR(this, kHeaderSize);
2182}
2183
2184
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002185uc16* SeqTwoByteString::GetChars() {
2186 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2187}
2188
2189
ager@chromium.org7c537e22008-10-16 08:43:32 +00002190uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002191 ASSERT(index >= 0 && index < length());
2192 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2193}
2194
2195
ager@chromium.org7c537e22008-10-16 08:43:32 +00002196void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002197 ASSERT(index >= 0 && index < length());
2198 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2199}
2200
2201
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002202int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002203 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002204}
2205
2206
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002207int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002208 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002209}
2210
2211
ager@chromium.org870a0b62008-11-04 11:43:05 +00002212String* ConsString::first() {
2213 return String::cast(READ_FIELD(this, kFirstOffset));
2214}
2215
2216
2217Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002218 return READ_FIELD(this, kFirstOffset);
2219}
2220
2221
ager@chromium.org870a0b62008-11-04 11:43:05 +00002222void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002223 WRITE_FIELD(this, kFirstOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002224 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002225}
2226
2227
ager@chromium.org870a0b62008-11-04 11:43:05 +00002228String* ConsString::second() {
2229 return String::cast(READ_FIELD(this, kSecondOffset));
2230}
2231
2232
2233Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002234 return READ_FIELD(this, kSecondOffset);
2235}
2236
2237
ager@chromium.org870a0b62008-11-04 11:43:05 +00002238void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002239 WRITE_FIELD(this, kSecondOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002240 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002241}
2242
2243
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002244ExternalAsciiString::Resource* ExternalAsciiString::resource() {
2245 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2246}
2247
2248
2249void ExternalAsciiString::set_resource(
2250 ExternalAsciiString::Resource* resource) {
2251 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2252}
2253
2254
2255ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
2256 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2257}
2258
2259
2260void ExternalTwoByteString::set_resource(
2261 ExternalTwoByteString::Resource* resource) {
2262 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2263}
2264
2265
ager@chromium.orgac091b72010-05-05 07:34:42 +00002266void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002267 set_finger_index(kEntriesIndex);
2268 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002269}
2270
2271
2272void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002273 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002274 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002275 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002276 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002277 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002278 MakeZeroSize();
2279}
2280
2281
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002282int JSFunctionResultCache::size() {
2283 return Smi::cast(get(kCacheSizeIndex))->value();
2284}
2285
2286
2287void JSFunctionResultCache::set_size(int size) {
2288 set(kCacheSizeIndex, Smi::FromInt(size));
2289}
2290
2291
2292int JSFunctionResultCache::finger_index() {
2293 return Smi::cast(get(kFingerIndex))->value();
2294}
2295
2296
2297void JSFunctionResultCache::set_finger_index(int finger_index) {
2298 set(kFingerIndex, Smi::FromInt(finger_index));
2299}
2300
2301
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002302byte ByteArray::get(int index) {
2303 ASSERT(index >= 0 && index < this->length());
2304 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2305}
2306
2307
2308void ByteArray::set(int index, byte value) {
2309 ASSERT(index >= 0 && index < this->length());
2310 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2311}
2312
2313
2314int ByteArray::get_int(int index) {
2315 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2316 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2317}
2318
2319
2320ByteArray* ByteArray::FromDataStartAddress(Address address) {
2321 ASSERT_TAG_ALIGNED(address);
2322 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2323}
2324
2325
2326Address ByteArray::GetDataStartAddress() {
2327 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2328}
2329
2330
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002331uint8_t* ExternalPixelArray::external_pixel_pointer() {
2332 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002333}
2334
2335
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002336uint8_t ExternalPixelArray::get(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002337 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002338 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002339 return ptr[index];
2340}
2341
2342
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002343void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002344 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002345 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002346 ptr[index] = value;
2347}
2348
2349
ager@chromium.org3811b432009-10-28 14:53:37 +00002350void* ExternalArray::external_pointer() {
2351 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2352 return reinterpret_cast<void*>(ptr);
2353}
2354
2355
2356void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2357 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2358 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2359}
2360
2361
2362int8_t ExternalByteArray::get(int index) {
2363 ASSERT((index >= 0) && (index < this->length()));
2364 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2365 return ptr[index];
2366}
2367
2368
2369void ExternalByteArray::set(int index, int8_t value) {
2370 ASSERT((index >= 0) && (index < this->length()));
2371 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2372 ptr[index] = value;
2373}
2374
2375
2376uint8_t ExternalUnsignedByteArray::get(int index) {
2377 ASSERT((index >= 0) && (index < this->length()));
2378 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2379 return ptr[index];
2380}
2381
2382
2383void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2384 ASSERT((index >= 0) && (index < this->length()));
2385 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2386 ptr[index] = value;
2387}
2388
2389
2390int16_t ExternalShortArray::get(int index) {
2391 ASSERT((index >= 0) && (index < this->length()));
2392 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2393 return ptr[index];
2394}
2395
2396
2397void ExternalShortArray::set(int index, int16_t value) {
2398 ASSERT((index >= 0) && (index < this->length()));
2399 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2400 ptr[index] = value;
2401}
2402
2403
2404uint16_t ExternalUnsignedShortArray::get(int index) {
2405 ASSERT((index >= 0) && (index < this->length()));
2406 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2407 return ptr[index];
2408}
2409
2410
2411void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2412 ASSERT((index >= 0) && (index < this->length()));
2413 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2414 ptr[index] = value;
2415}
2416
2417
2418int32_t ExternalIntArray::get(int index) {
2419 ASSERT((index >= 0) && (index < this->length()));
2420 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2421 return ptr[index];
2422}
2423
2424
2425void ExternalIntArray::set(int index, int32_t value) {
2426 ASSERT((index >= 0) && (index < this->length()));
2427 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2428 ptr[index] = value;
2429}
2430
2431
2432uint32_t ExternalUnsignedIntArray::get(int index) {
2433 ASSERT((index >= 0) && (index < this->length()));
2434 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2435 return ptr[index];
2436}
2437
2438
2439void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2440 ASSERT((index >= 0) && (index < this->length()));
2441 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2442 ptr[index] = value;
2443}
2444
2445
2446float ExternalFloatArray::get(int index) {
2447 ASSERT((index >= 0) && (index < this->length()));
2448 float* ptr = static_cast<float*>(external_pointer());
2449 return ptr[index];
2450}
2451
2452
2453void ExternalFloatArray::set(int index, float value) {
2454 ASSERT((index >= 0) && (index < this->length()));
2455 float* ptr = static_cast<float*>(external_pointer());
2456 ptr[index] = value;
2457}
2458
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002459
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002460double ExternalDoubleArray::get(int index) {
2461 ASSERT((index >= 0) && (index < this->length()));
2462 double* ptr = static_cast<double*>(external_pointer());
2463 return ptr[index];
2464}
2465
2466
2467void ExternalDoubleArray::set(int index, double value) {
2468 ASSERT((index >= 0) && (index < this->length()));
2469 double* ptr = static_cast<double*>(external_pointer());
2470 ptr[index] = value;
2471}
2472
2473
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002474int Map::visitor_id() {
2475 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2476}
2477
2478
2479void Map::set_visitor_id(int id) {
2480 ASSERT(0 <= id && id < 256);
2481 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2482}
2483
ager@chromium.org3811b432009-10-28 14:53:37 +00002484
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002485int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002486 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2487}
2488
2489
2490int Map::inobject_properties() {
2491 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002492}
2493
2494
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002495int Map::pre_allocated_property_fields() {
2496 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2497}
2498
2499
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002500int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002501 int instance_size = map->instance_size();
2502 if (instance_size != kVariableSizeSentinel) return instance_size;
2503 // We can ignore the "symbol" bit becase it is only set for symbols
2504 // and implies a string type.
2505 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002506 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002507 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002508 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002509 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002510 if (instance_type == ASCII_STRING_TYPE) {
2511 return SeqAsciiString::SizeFor(
2512 reinterpret_cast<SeqAsciiString*>(this)->length());
2513 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002514 if (instance_type == BYTE_ARRAY_TYPE) {
2515 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2516 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002517 if (instance_type == STRING_TYPE) {
2518 return SeqTwoByteString::SizeFor(
2519 reinterpret_cast<SeqTwoByteString*>(this)->length());
2520 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002521 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2522 return FixedDoubleArray::SizeFor(
2523 reinterpret_cast<FixedDoubleArray*>(this)->length());
2524 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002525 ASSERT(instance_type == CODE_TYPE);
2526 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002527}
2528
2529
2530void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002531 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002532 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002533 ASSERT(0 <= value && value < 256);
2534 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2535}
2536
2537
ager@chromium.org7c537e22008-10-16 08:43:32 +00002538void Map::set_inobject_properties(int value) {
2539 ASSERT(0 <= value && value < 256);
2540 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2541}
2542
2543
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002544void Map::set_pre_allocated_property_fields(int value) {
2545 ASSERT(0 <= value && value < 256);
2546 WRITE_BYTE_FIELD(this,
2547 kPreAllocatedPropertyFieldsOffset,
2548 static_cast<byte>(value));
2549}
2550
2551
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002552InstanceType Map::instance_type() {
2553 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2554}
2555
2556
2557void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002558 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2559}
2560
2561
2562int Map::unused_property_fields() {
2563 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2564}
2565
2566
2567void Map::set_unused_property_fields(int value) {
2568 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2569}
2570
2571
2572byte Map::bit_field() {
2573 return READ_BYTE_FIELD(this, kBitFieldOffset);
2574}
2575
2576
2577void Map::set_bit_field(byte value) {
2578 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2579}
2580
2581
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002582byte Map::bit_field2() {
2583 return READ_BYTE_FIELD(this, kBitField2Offset);
2584}
2585
2586
2587void Map::set_bit_field2(byte value) {
2588 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2589}
2590
2591
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002592void Map::set_non_instance_prototype(bool value) {
2593 if (value) {
2594 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2595 } else {
2596 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2597 }
2598}
2599
2600
2601bool Map::has_non_instance_prototype() {
2602 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2603}
2604
2605
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002606void Map::set_function_with_prototype(bool value) {
2607 if (value) {
2608 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2609 } else {
2610 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2611 }
2612}
2613
2614
2615bool Map::function_with_prototype() {
2616 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2617}
2618
2619
ager@chromium.org870a0b62008-11-04 11:43:05 +00002620void Map::set_is_access_check_needed(bool access_check_needed) {
2621 if (access_check_needed) {
2622 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2623 } else {
2624 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2625 }
2626}
2627
2628
2629bool Map::is_access_check_needed() {
2630 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2631}
2632
2633
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002634void Map::set_is_extensible(bool value) {
2635 if (value) {
2636 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2637 } else {
2638 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2639 }
2640}
2641
2642bool Map::is_extensible() {
2643 return ((1 << kIsExtensible) & bit_field2()) != 0;
2644}
2645
2646
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002647void Map::set_attached_to_shared_function_info(bool value) {
2648 if (value) {
2649 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2650 } else {
2651 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2652 }
2653}
2654
2655bool Map::attached_to_shared_function_info() {
2656 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2657}
2658
2659
2660void Map::set_is_shared(bool value) {
2661 if (value) {
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 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002664 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002665 }
2666}
2667
2668bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002669 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002670}
2671
2672
2673JSFunction* Map::unchecked_constructor() {
2674 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2675}
2676
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002677
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002678FixedArray* Map::unchecked_prototype_transitions() {
2679 return reinterpret_cast<FixedArray*>(
2680 READ_FIELD(this, kPrototypeTransitionsOffset));
2681}
2682
2683
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002684Code::Flags Code::flags() {
2685 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2686}
2687
2688
2689void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002690 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002691 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002692 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2693 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002694 ExtractArgumentsCountFromFlags(flags) >= 0);
2695 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2696}
2697
2698
2699Code::Kind Code::kind() {
2700 return ExtractKindFromFlags(flags());
2701}
2702
2703
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002704InLoopFlag Code::ic_in_loop() {
2705 return ExtractICInLoopFromFlags(flags());
2706}
2707
2708
kasper.lund7276f142008-07-30 08:49:36 +00002709InlineCacheState Code::ic_state() {
2710 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002711 // Only allow uninitialized or debugger states for non-IC code
2712 // objects. This is used in the debugger to determine whether or not
2713 // a call to code object has been replaced with a debug break call.
2714 ASSERT(is_inline_cache_stub() ||
2715 result == UNINITIALIZED ||
2716 result == DEBUG_BREAK ||
2717 result == DEBUG_PREPARE_STEP_IN);
2718 return result;
2719}
2720
2721
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002722Code::ExtraICState Code::extra_ic_state() {
2723 ASSERT(is_inline_cache_stub());
2724 return ExtractExtraICStateFromFlags(flags());
2725}
2726
2727
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002728PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002729 return ExtractTypeFromFlags(flags());
2730}
2731
2732
2733int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002734 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002735 return ExtractArgumentsCountFromFlags(flags());
2736}
2737
2738
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002739int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002740 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002741 kind() == UNARY_OP_IC ||
2742 kind() == BINARY_OP_IC ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002743 kind() == COMPARE_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002744 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002745}
2746
2747
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002748void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002749 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002750 kind() == UNARY_OP_IC ||
2751 kind() == BINARY_OP_IC ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002752 kind() == COMPARE_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002753 ASSERT(0 <= major && major < 256);
2754 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002755}
2756
2757
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002758bool Code::optimizable() {
2759 ASSERT(kind() == FUNCTION);
2760 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2761}
2762
2763
2764void Code::set_optimizable(bool value) {
2765 ASSERT(kind() == FUNCTION);
2766 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2767}
2768
2769
2770bool Code::has_deoptimization_support() {
2771 ASSERT(kind() == FUNCTION);
2772 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2773}
2774
2775
2776void Code::set_has_deoptimization_support(bool value) {
2777 ASSERT(kind() == FUNCTION);
2778 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2779}
2780
2781
2782int Code::allow_osr_at_loop_nesting_level() {
2783 ASSERT(kind() == FUNCTION);
2784 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2785}
2786
2787
2788void Code::set_allow_osr_at_loop_nesting_level(int level) {
2789 ASSERT(kind() == FUNCTION);
2790 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2791 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2792}
2793
2794
2795unsigned Code::stack_slots() {
2796 ASSERT(kind() == OPTIMIZED_FUNCTION);
2797 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2798}
2799
2800
2801void Code::set_stack_slots(unsigned slots) {
2802 ASSERT(kind() == OPTIMIZED_FUNCTION);
2803 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2804}
2805
2806
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002807unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002808 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002809 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002810}
2811
2812
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002813void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002814 ASSERT(kind() == OPTIMIZED_FUNCTION);
2815 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002816 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002817}
2818
2819
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002820unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002821 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002822 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002823}
2824
2825
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002826void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002827 ASSERT(kind() == FUNCTION);
2828 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002829 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002830}
2831
2832
2833CheckType Code::check_type() {
2834 ASSERT(is_call_stub() || is_keyed_call_stub());
2835 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2836 return static_cast<CheckType>(type);
2837}
2838
2839
2840void Code::set_check_type(CheckType value) {
2841 ASSERT(is_call_stub() || is_keyed_call_stub());
2842 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2843}
2844
2845
danno@chromium.org40cb8782011-05-25 07:58:50 +00002846byte Code::unary_op_type() {
2847 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002848 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
2849}
2850
2851
danno@chromium.org40cb8782011-05-25 07:58:50 +00002852void Code::set_unary_op_type(byte value) {
2853 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002854 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
2855}
2856
2857
danno@chromium.org40cb8782011-05-25 07:58:50 +00002858byte Code::binary_op_type() {
2859 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002860 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2861}
2862
2863
danno@chromium.org40cb8782011-05-25 07:58:50 +00002864void Code::set_binary_op_type(byte value) {
2865 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002866 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2867}
2868
2869
danno@chromium.org40cb8782011-05-25 07:58:50 +00002870byte Code::binary_op_result_type() {
2871 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002872 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2873}
2874
2875
danno@chromium.org40cb8782011-05-25 07:58:50 +00002876void Code::set_binary_op_result_type(byte value) {
2877 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002878 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2879}
2880
2881
2882byte Code::compare_state() {
2883 ASSERT(is_compare_ic_stub());
2884 return READ_BYTE_FIELD(this, kCompareStateOffset);
2885}
2886
2887
2888void Code::set_compare_state(byte value) {
2889 ASSERT(is_compare_ic_stub());
2890 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2891}
2892
2893
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002894bool Code::is_inline_cache_stub() {
2895 Kind kind = this->kind();
2896 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2897}
2898
2899
2900Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002901 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002902 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002903 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002904 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002905 int argc,
2906 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002907 // Extra IC state is only allowed for call IC stubs or for store IC
2908 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002909 ASSERT(extra_ic_state == kNoExtraICState ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002910 (kind == CALL_IC) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00002911 (kind == STORE_IC) ||
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002912 (kind == KEYED_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002913 // Compute the bit mask.
2914 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002915 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002916 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002917 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002918 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002919 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002920 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002921 // Cast to flags and validate result before returning it.
2922 Flags result = static_cast<Flags>(bits);
2923 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002924 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002925 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002926 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002927 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002928 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2929 return result;
2930}
2931
2932
2933Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2934 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002935 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002936 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002937 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002938 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002939 return ComputeFlags(
2940 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002941}
2942
2943
2944Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2945 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2946 return static_cast<Kind>(bits);
2947}
2948
2949
kasper.lund7276f142008-07-30 08:49:36 +00002950InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2951 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002952 return static_cast<InlineCacheState>(bits);
2953}
2954
2955
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002956Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
2957 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
2958 return static_cast<ExtraICState>(bits);
2959}
2960
2961
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002962InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2963 int bits = (flags & kFlagsICInLoopMask);
2964 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2965}
2966
2967
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002968PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2969 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2970 return static_cast<PropertyType>(bits);
2971}
2972
2973
2974int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2975 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2976}
2977
2978
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002979InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2980 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2981 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2982}
2983
2984
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002985Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2986 int bits = flags & ~kFlagsTypeMask;
2987 return static_cast<Flags>(bits);
2988}
2989
2990
ager@chromium.org8bb60582008-12-11 12:02:20 +00002991Code* Code::GetCodeFromTargetAddress(Address address) {
2992 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2993 // GetCodeFromTargetAddress might be called when marking objects during mark
2994 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2995 // Code::cast. Code::cast does not work when the object's map is
2996 // marked.
2997 Code* result = reinterpret_cast<Code*>(code);
2998 return result;
2999}
3000
3001
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003002Isolate* Map::isolate() {
3003 return heap()->isolate();
3004}
3005
3006
3007Heap* Map::heap() {
3008 // NOTE: address() helper is not used to save one instruction.
3009 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3010 ASSERT(heap != NULL);
3011 ASSERT(heap->isolate() == Isolate::Current());
3012 return heap;
3013}
3014
3015
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003016Heap* Code::heap() {
3017 // NOTE: address() helper is not used to save one instruction.
3018 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3019 ASSERT(heap != NULL);
3020 ASSERT(heap->isolate() == Isolate::Current());
3021 return heap;
3022}
3023
3024
3025Isolate* Code::isolate() {
3026 return heap()->isolate();
3027}
3028
3029
3030Heap* JSGlobalPropertyCell::heap() {
3031 // NOTE: address() helper is not used to save one instruction.
3032 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3033 ASSERT(heap != NULL);
3034 ASSERT(heap->isolate() == Isolate::Current());
3035 return heap;
3036}
3037
3038
3039Isolate* JSGlobalPropertyCell::isolate() {
3040 return heap()->isolate();
3041}
3042
3043
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003044Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3045 return HeapObject::
3046 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3047}
3048
3049
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003050Object* Map::prototype() {
3051 return READ_FIELD(this, kPrototypeOffset);
3052}
3053
3054
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003055void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003056 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003057 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003058 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003059}
3060
3061
lrn@chromium.org303ada72010-10-27 09:33:13 +00003062MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003063 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003064 Object* obj;
3065 { MaybeObject* maybe_obj = CopyDropTransitions();
3066 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3067 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003068 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003069 new_map->set_elements_kind(JSObject::FAST_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003070 isolate()->counters()->map_to_fast_elements()->Increment();
3071 return new_map;
3072}
3073
3074
3075MaybeObject* Map::GetFastDoubleElementsMap() {
3076 if (has_fast_double_elements()) return this;
3077 Object* obj;
3078 { MaybeObject* maybe_obj = CopyDropTransitions();
3079 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3080 }
3081 Map* new_map = Map::cast(obj);
3082 new_map->set_elements_kind(JSObject::FAST_DOUBLE_ELEMENTS);
3083 isolate()->counters()->map_to_fast_double_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003084 return new_map;
3085}
3086
3087
lrn@chromium.org303ada72010-10-27 09:33:13 +00003088MaybeObject* Map::GetSlowElementsMap() {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003089 if (!has_fast_elements() && !has_fast_double_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003090 Object* obj;
3091 { MaybeObject* maybe_obj = CopyDropTransitions();
3092 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3093 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003094 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003095 new_map->set_elements_kind(JSObject::DICTIONARY_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003096 isolate()->counters()->map_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003097 return new_map;
3098}
3099
3100
danno@chromium.org40cb8782011-05-25 07:58:50 +00003101DescriptorArray* Map::instance_descriptors() {
3102 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3103 if (object->IsSmi()) {
3104 return HEAP->empty_descriptor_array();
3105 } else {
3106 return DescriptorArray::cast(object);
3107 }
3108}
3109
3110
3111void Map::init_instance_descriptors() {
3112 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3113}
3114
3115
3116void Map::clear_instance_descriptors() {
3117 Object* object = READ_FIELD(this,
3118 kInstanceDescriptorsOrBitField3Offset);
3119 if (!object->IsSmi()) {
3120 WRITE_FIELD(
3121 this,
3122 kInstanceDescriptorsOrBitField3Offset,
3123 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3124 }
3125}
3126
3127
3128void Map::set_instance_descriptors(DescriptorArray* value,
3129 WriteBarrierMode mode) {
3130 Object* object = READ_FIELD(this,
3131 kInstanceDescriptorsOrBitField3Offset);
3132 if (value == isolate()->heap()->empty_descriptor_array()) {
3133 clear_instance_descriptors();
3134 return;
3135 } else {
3136 if (object->IsSmi()) {
3137 value->set_bit_field3_storage(Smi::cast(object)->value());
3138 } else {
3139 value->set_bit_field3_storage(
3140 DescriptorArray::cast(object)->bit_field3_storage());
3141 }
3142 }
3143 ASSERT(!is_shared());
3144 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
3145 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3146 this,
3147 kInstanceDescriptorsOrBitField3Offset,
3148 mode);
3149}
3150
3151
3152int Map::bit_field3() {
3153 Object* object = READ_FIELD(this,
3154 kInstanceDescriptorsOrBitField3Offset);
3155 if (object->IsSmi()) {
3156 return Smi::cast(object)->value();
3157 } else {
3158 return DescriptorArray::cast(object)->bit_field3_storage();
3159 }
3160}
3161
3162
3163void Map::set_bit_field3(int value) {
3164 ASSERT(Smi::IsValid(value));
3165 Object* object = READ_FIELD(this,
3166 kInstanceDescriptorsOrBitField3Offset);
3167 if (object->IsSmi()) {
3168 WRITE_FIELD(this,
3169 kInstanceDescriptorsOrBitField3Offset,
3170 Smi::FromInt(value));
3171 } else {
3172 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3173 }
3174}
3175
3176
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003177ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003178ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003179ACCESSORS(Map, constructor, Object, kConstructorOffset)
3180
3181ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
3182ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003183ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
3184 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003185
3186ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3187ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003188ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003189
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003190ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003191
3192ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3193ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3194ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3195ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3196ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3197
3198ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3199ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3200ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3201
3202ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3203ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3204ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3205ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3206ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3207ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3208
3209ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3210ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3211
3212ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3213ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3214
3215ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3216ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003217ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3218 kPropertyAccessorsOffset)
3219ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3220 kPrototypeTemplateOffset)
3221ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3222ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3223 kNamedPropertyHandlerOffset)
3224ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3225 kIndexedPropertyHandlerOffset)
3226ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3227 kInstanceTemplateOffset)
3228ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3229ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003230ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3231 kInstanceCallHandlerOffset)
3232ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3233 kAccessCheckInfoOffset)
3234ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3235
3236ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003237ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3238 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003239
3240ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3241ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3242
3243ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3244
3245ACCESSORS(Script, source, Object, kSourceOffset)
3246ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003247ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003248ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3249ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003250ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003251ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003252ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003253ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003254ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003255ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003256ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003257ACCESSORS(Script, eval_from_instructions_offset, Smi,
3258 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003259
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003260#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003261ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3262ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3263ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3264ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3265
3266ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3267ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3268ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3269ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003270#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003271
3272ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003273ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3274ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003275ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3276 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003277ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003278ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3279ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003280ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003281ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3282 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003283
3284BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3285 kHiddenPrototypeBit)
3286BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3287BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3288 kNeedsAccessCheckBit)
3289BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3290 kIsExpressionBit)
3291BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3292 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003293BOOL_GETTER(SharedFunctionInfo,
3294 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003295 has_only_simple_this_property_assignments,
3296 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003297BOOL_ACCESSORS(SharedFunctionInfo,
3298 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003299 allows_lazy_compilation,
3300 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003301BOOL_ACCESSORS(SharedFunctionInfo,
3302 compiler_hints,
3303 uses_arguments,
3304 kUsesArguments)
3305BOOL_ACCESSORS(SharedFunctionInfo,
3306 compiler_hints,
3307 has_duplicate_parameters,
3308 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003309
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003310
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003311#if V8_HOST_ARCH_32_BIT
3312SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3313SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003314 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003315SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003316 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003317SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3318SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003319 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003320SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3321SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003322 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003323SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003324 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003325SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003326 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003327SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003328#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003329
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003330#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003331 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003332 int holder::name() { \
3333 int value = READ_INT_FIELD(this, offset); \
3334 ASSERT(kHeapObjectTag == 1); \
3335 ASSERT((value & kHeapObjectTag) == 0); \
3336 return value >> 1; \
3337 } \
3338 void holder::set_##name(int value) { \
3339 ASSERT(kHeapObjectTag == 1); \
3340 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3341 (value & 0xC0000000) == 0x000000000); \
3342 WRITE_INT_FIELD(this, \
3343 offset, \
3344 (value << 1) & ~kHeapObjectTag); \
3345 }
3346
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003347#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3348 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003349 INT_ACCESSORS(holder, name, offset)
3350
3351
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003352PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003353PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3354 formal_parameter_count,
3355 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003356
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003357PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3358 expected_nof_properties,
3359 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003360PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3361
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003362PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3363PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3364 start_position_and_type,
3365 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003366
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003367PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3368 function_token_position,
3369 kFunctionTokenPositionOffset)
3370PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3371 compiler_hints,
3372 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003373
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003374PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3375 this_property_assignments_count,
3376 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003377PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003378#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003379
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003380
3381int SharedFunctionInfo::construction_count() {
3382 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3383}
3384
3385
3386void SharedFunctionInfo::set_construction_count(int value) {
3387 ASSERT(0 <= value && value < 256);
3388 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3389}
3390
3391
whesse@chromium.org7b260152011-06-20 15:33:18 +00003392BOOL_ACCESSORS(SharedFunctionInfo,
3393 compiler_hints,
3394 live_objects_may_exist,
3395 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003396
3397
3398bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003399 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003400}
3401
3402
whesse@chromium.org7b260152011-06-20 15:33:18 +00003403BOOL_GETTER(SharedFunctionInfo,
3404 compiler_hints,
3405 optimization_disabled,
3406 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003407
3408
3409void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3410 set_compiler_hints(BooleanBit::set(compiler_hints(),
3411 kOptimizationDisabled,
3412 disable));
3413 // If disabling optimizations we reflect that in the code object so
3414 // it will not be counted as optimizable code.
3415 if ((code()->kind() == Code::FUNCTION) && disable) {
3416 code()->set_optimizable(false);
3417 }
3418}
3419
3420
whesse@chromium.org7b260152011-06-20 15:33:18 +00003421BOOL_ACCESSORS(SharedFunctionInfo,
3422 compiler_hints,
3423 strict_mode,
3424 kStrictModeFunction)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003425
3426
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003427bool SharedFunctionInfo::native() {
3428 return BooleanBit::get(compiler_hints(), kNative);
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003429}
3430
3431
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003432void SharedFunctionInfo::set_native(bool value) {
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003433 set_compiler_hints(BooleanBit::set(compiler_hints(),
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003434 kNative,
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003435 value));
3436}
3437
3438
whesse@chromium.org7b260152011-06-20 15:33:18 +00003439bool SharedFunctionInfo::bound() {
3440 return BooleanBit::get(compiler_hints(), kBoundFunction);
3441}
3442
3443
3444void SharedFunctionInfo::set_bound(bool value) {
3445 set_compiler_hints(BooleanBit::set(compiler_hints(),
3446 kBoundFunction,
3447 value));
3448}
3449
3450
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003451ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3452ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3453
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003454ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3455
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003456bool Script::HasValidSource() {
3457 Object* src = this->source();
3458 if (!src->IsString()) return true;
3459 String* src_str = String::cast(src);
3460 if (!StringShape(src_str).IsExternal()) return true;
3461 if (src_str->IsAsciiRepresentation()) {
3462 return ExternalAsciiString::cast(src)->resource() != NULL;
3463 } else if (src_str->IsTwoByteRepresentation()) {
3464 return ExternalTwoByteString::cast(src)->resource() != NULL;
3465 }
3466 return true;
3467}
3468
3469
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003470void SharedFunctionInfo::DontAdaptArguments() {
3471 ASSERT(code()->kind() == Code::BUILTIN);
3472 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3473}
3474
3475
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003476int SharedFunctionInfo::start_position() {
3477 return start_position_and_type() >> kStartPositionShift;
3478}
3479
3480
3481void SharedFunctionInfo::set_start_position(int start_position) {
3482 set_start_position_and_type((start_position << kStartPositionShift)
3483 | (start_position_and_type() & ~kStartPositionMask));
3484}
3485
3486
3487Code* SharedFunctionInfo::code() {
3488 return Code::cast(READ_FIELD(this, kCodeOffset));
3489}
3490
3491
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003492Code* SharedFunctionInfo::unchecked_code() {
3493 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3494}
3495
3496
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003497void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003498 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003499 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003500}
3501
3502
ager@chromium.orgb5737492010-07-15 09:29:43 +00003503SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3504 return reinterpret_cast<SerializedScopeInfo*>(
3505 READ_FIELD(this, kScopeInfoOffset));
3506}
3507
3508
3509void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3510 WriteBarrierMode mode) {
3511 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003512 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003513}
3514
3515
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003516Smi* SharedFunctionInfo::deopt_counter() {
3517 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3518}
3519
3520
3521void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3522 WRITE_FIELD(this, kDeoptCounterOffset, value);
3523}
3524
3525
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003526bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003527 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003528 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003529}
3530
3531
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003532bool SharedFunctionInfo::IsApiFunction() {
3533 return function_data()->IsFunctionTemplateInfo();
3534}
3535
3536
3537FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3538 ASSERT(IsApiFunction());
3539 return FunctionTemplateInfo::cast(function_data());
3540}
3541
3542
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003543bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003544 return function_data()->IsSmi();
3545}
3546
3547
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003548BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3549 ASSERT(HasBuiltinFunctionId());
3550 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003551}
3552
3553
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003554int SharedFunctionInfo::code_age() {
3555 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3556}
3557
3558
3559void SharedFunctionInfo::set_code_age(int code_age) {
3560 set_compiler_hints(compiler_hints() |
3561 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3562}
3563
3564
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003565bool SharedFunctionInfo::has_deoptimization_support() {
3566 Code* code = this->code();
3567 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3568}
3569
3570
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003571bool JSFunction::IsBuiltin() {
3572 return context()->global()->IsJSBuiltinsObject();
3573}
3574
3575
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003576bool JSFunction::NeedsArgumentsAdaption() {
3577 return shared()->formal_parameter_count() !=
3578 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3579}
3580
3581
3582bool JSFunction::IsOptimized() {
3583 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3584}
3585
3586
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003587bool JSFunction::IsOptimizable() {
3588 return code()->kind() == Code::FUNCTION && code()->optimizable();
3589}
3590
3591
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003592bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003593 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003594}
3595
3596
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003597Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003598 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003599}
3600
3601
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003602Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003603 return reinterpret_cast<Code*>(
3604 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003605}
3606
3607
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003608void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003609 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003610 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003611 Address entry = value->entry();
3612 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003613}
3614
3615
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003616void JSFunction::ReplaceCode(Code* code) {
3617 bool was_optimized = IsOptimized();
3618 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3619
3620 set_code(code);
3621
3622 // Add/remove the function from the list of optimized functions for this
3623 // context based on the state change.
3624 if (!was_optimized && is_optimized) {
3625 context()->global_context()->AddOptimizedFunction(this);
3626 }
3627 if (was_optimized && !is_optimized) {
3628 context()->global_context()->RemoveOptimizedFunction(this);
3629 }
3630}
3631
3632
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003633Context* JSFunction::context() {
3634 return Context::cast(READ_FIELD(this, kContextOffset));
3635}
3636
3637
3638Object* JSFunction::unchecked_context() {
3639 return READ_FIELD(this, kContextOffset);
3640}
3641
3642
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003643SharedFunctionInfo* JSFunction::unchecked_shared() {
3644 return reinterpret_cast<SharedFunctionInfo*>(
3645 READ_FIELD(this, kSharedFunctionInfoOffset));
3646}
3647
3648
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003649void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003650 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003651 WRITE_FIELD(this, kContextOffset, value);
3652 WRITE_BARRIER(this, kContextOffset);
3653}
3654
3655ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3656 kPrototypeOrInitialMapOffset)
3657
3658
3659Map* JSFunction::initial_map() {
3660 return Map::cast(prototype_or_initial_map());
3661}
3662
3663
3664void JSFunction::set_initial_map(Map* value) {
3665 set_prototype_or_initial_map(value);
3666}
3667
3668
3669bool JSFunction::has_initial_map() {
3670 return prototype_or_initial_map()->IsMap();
3671}
3672
3673
3674bool JSFunction::has_instance_prototype() {
3675 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3676}
3677
3678
3679bool JSFunction::has_prototype() {
3680 return map()->has_non_instance_prototype() || has_instance_prototype();
3681}
3682
3683
3684Object* JSFunction::instance_prototype() {
3685 ASSERT(has_instance_prototype());
3686 if (has_initial_map()) return initial_map()->prototype();
3687 // When there is no initial map and the prototype is a JSObject, the
3688 // initial map field is used for the prototype field.
3689 return prototype_or_initial_map();
3690}
3691
3692
3693Object* JSFunction::prototype() {
3694 ASSERT(has_prototype());
3695 // If the function's prototype property has been set to a non-JSObject
3696 // value, that value is stored in the constructor field of the map.
3697 if (map()->has_non_instance_prototype()) return map()->constructor();
3698 return instance_prototype();
3699}
3700
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003701bool JSFunction::should_have_prototype() {
3702 return map()->function_with_prototype();
3703}
3704
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003705
3706bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003707 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003708}
3709
3710
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003711int JSFunction::NumberOfLiterals() {
3712 return literals()->length();
3713}
3714
3715
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003716Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003717 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003718 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003719}
3720
3721
3722void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3723 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003724 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003725 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3726 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3727}
3728
3729
3730Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003731 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003732 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3733}
3734
3735
3736void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3737 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003738 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003739 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003740 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003741}
3742
3743
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003744ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
3745
3746
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003747Address Foreign::address() {
3748 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003749}
3750
3751
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003752void Foreign::set_address(Address value) {
3753 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003754}
3755
3756
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003757ACCESSORS(JSValue, value, Object, kValueOffset)
3758
3759
3760JSValue* JSValue::cast(Object* obj) {
3761 ASSERT(obj->IsJSValue());
3762 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3763 return reinterpret_cast<JSValue*>(obj);
3764}
3765
3766
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003767ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3768ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3769ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3770ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3771ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3772SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3773SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3774
3775
3776JSMessageObject* JSMessageObject::cast(Object* obj) {
3777 ASSERT(obj->IsJSMessageObject());
3778 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3779 return reinterpret_cast<JSMessageObject*>(obj);
3780}
3781
3782
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003783INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003784ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003785ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003786ACCESSORS(Code, next_code_flushing_candidate,
3787 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003788
3789
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003790byte* Code::instruction_start() {
3791 return FIELD_ADDR(this, kHeaderSize);
3792}
3793
3794
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003795byte* Code::instruction_end() {
3796 return instruction_start() + instruction_size();
3797}
3798
3799
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003800int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003801 return RoundUp(instruction_size(), kObjectAlignment);
3802}
3803
3804
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003805FixedArray* Code::unchecked_deoptimization_data() {
3806 return reinterpret_cast<FixedArray*>(
3807 READ_FIELD(this, kDeoptimizationDataOffset));
3808}
3809
3810
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003811ByteArray* Code::unchecked_relocation_info() {
3812 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003813}
3814
3815
3816byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003817 return unchecked_relocation_info()->GetDataStartAddress();
3818}
3819
3820
3821int Code::relocation_size() {
3822 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003823}
3824
3825
3826byte* Code::entry() {
3827 return instruction_start();
3828}
3829
3830
3831bool Code::contains(byte* pc) {
3832 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003833 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003834}
3835
3836
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003837ACCESSORS(JSArray, length, Object, kLengthOffset)
3838
3839
ager@chromium.org236ad962008-09-25 09:45:57 +00003840ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003841
3842
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003843JSRegExp::Type JSRegExp::TypeTag() {
3844 Object* data = this->data();
3845 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3846 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3847 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003848}
3849
3850
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003851int JSRegExp::CaptureCount() {
3852 switch (TypeTag()) {
3853 case ATOM:
3854 return 0;
3855 case IRREGEXP:
3856 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3857 default:
3858 UNREACHABLE();
3859 return -1;
3860 }
3861}
3862
3863
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003864JSRegExp::Flags JSRegExp::GetFlags() {
3865 ASSERT(this->data()->IsFixedArray());
3866 Object* data = this->data();
3867 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3868 return Flags(smi->value());
3869}
3870
3871
3872String* JSRegExp::Pattern() {
3873 ASSERT(this->data()->IsFixedArray());
3874 Object* data = this->data();
3875 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3876 return pattern;
3877}
3878
3879
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003880Object* JSRegExp::DataAt(int index) {
3881 ASSERT(TypeTag() != NOT_COMPILED);
3882 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003883}
3884
3885
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003886void JSRegExp::SetDataAt(int index, Object* value) {
3887 ASSERT(TypeTag() != NOT_COMPILED);
3888 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3889 FixedArray::cast(data())->set(index, value);
3890}
3891
3892
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003893JSObject::ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003894 ElementsKind kind = map()->elements_kind();
3895 ASSERT((kind == FAST_ELEMENTS &&
3896 (elements()->map() == GetHeap()->fixed_array_map() ||
3897 elements()->map() == GetHeap()->fixed_cow_array_map())) ||
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003898 (kind == FAST_DOUBLE_ELEMENTS &&
3899 elements()->IsFixedDoubleArray()) ||
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003900 (kind == DICTIONARY_ELEMENTS &&
3901 elements()->IsFixedArray() &&
3902 elements()->IsDictionary()) ||
3903 (kind > DICTIONARY_ELEMENTS));
3904 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003905}
3906
3907
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003908bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003909 return GetElementsKind() == FAST_ELEMENTS;
3910}
3911
3912
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003913bool JSObject::HasFastDoubleElements() {
3914 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
3915}
3916
3917
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003918bool JSObject::HasDictionaryElements() {
3919 return GetElementsKind() == DICTIONARY_ELEMENTS;
3920}
3921
3922
ager@chromium.org3811b432009-10-28 14:53:37 +00003923bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003924 HeapObject* array = elements();
3925 ASSERT(array != NULL);
3926 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00003927}
3928
3929
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003930#define EXTERNAL_ELEMENTS_CHECK(name, type) \
3931bool JSObject::HasExternal##name##Elements() { \
3932 HeapObject* array = elements(); \
3933 ASSERT(array != NULL); \
3934 if (!array->IsHeapObject()) \
3935 return false; \
3936 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00003937}
3938
3939
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003940EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
3941EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
3942EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
3943EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
3944 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
3945EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
3946EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
3947 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
3948EXTERNAL_ELEMENTS_CHECK(Float,
3949 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003950EXTERNAL_ELEMENTS_CHECK(Double,
3951 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003952EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00003953
3954
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003955bool JSObject::HasNamedInterceptor() {
3956 return map()->has_named_interceptor();
3957}
3958
3959
3960bool JSObject::HasIndexedInterceptor() {
3961 return map()->has_indexed_interceptor();
3962}
3963
3964
ager@chromium.org5c838252010-02-19 08:53:10 +00003965bool JSObject::AllowsSetElementsLength() {
3966 bool result = elements()->IsFixedArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003967 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00003968 return result;
3969}
3970
3971
lrn@chromium.org303ada72010-10-27 09:33:13 +00003972MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003973 ASSERT(HasFastElements());
3974 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003975 Isolate* isolate = GetIsolate();
3976 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003977 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003978 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
3979 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00003980 if (!maybe_writable_elems->ToObject(&writable_elems)) {
3981 return maybe_writable_elems;
3982 }
3983 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003984 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003985 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003986 return writable_elems;
3987}
3988
3989
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003990StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003991 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003992 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003993}
3994
3995
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003996NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003997 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003998 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003999}
4000
4001
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004002bool String::IsHashFieldComputed(uint32_t field) {
4003 return (field & kHashNotComputedMask) == 0;
4004}
4005
4006
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004007bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004008 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004009}
4010
4011
4012uint32_t String::Hash() {
4013 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004014 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004015 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004016 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004017 return ComputeAndSetHash();
4018}
4019
4020
ager@chromium.org7c537e22008-10-16 08:43:32 +00004021StringHasher::StringHasher(int length)
4022 : length_(length),
4023 raw_running_hash_(0),
4024 array_index_(0),
4025 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4026 is_first_char_(true),
4027 is_valid_(true) { }
4028
4029
4030bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004031 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004032}
4033
4034
4035void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004036 // Use the Jenkins one-at-a-time hash function to update the hash
4037 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004038 raw_running_hash_ += c;
4039 raw_running_hash_ += (raw_running_hash_ << 10);
4040 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004041 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004042 if (is_array_index_) {
4043 if (c < '0' || c > '9') {
4044 is_array_index_ = false;
4045 } else {
4046 int d = c - '0';
4047 if (is_first_char_) {
4048 is_first_char_ = false;
4049 if (c == '0' && length_ > 1) {
4050 is_array_index_ = false;
4051 return;
4052 }
4053 }
4054 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4055 is_array_index_ = false;
4056 } else {
4057 array_index_ = array_index_ * 10 + d;
4058 }
4059 }
4060 }
4061}
4062
4063
4064void StringHasher::AddCharacterNoIndex(uc32 c) {
4065 ASSERT(!is_array_index());
4066 raw_running_hash_ += c;
4067 raw_running_hash_ += (raw_running_hash_ << 10);
4068 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4069}
4070
4071
4072uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004073 // Get the calculated raw hash value and do some more bit ops to distribute
4074 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004075 uint32_t result = raw_running_hash_;
4076 result += (result << 3);
4077 result ^= (result >> 11);
4078 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004079 if (result == 0) {
4080 result = 27;
4081 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004082 return result;
4083}
4084
4085
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004086template <typename schar>
4087uint32_t HashSequentialString(const schar* chars, int length) {
4088 StringHasher hasher(length);
4089 if (!hasher.has_trivial_hash()) {
4090 int i;
4091 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4092 hasher.AddCharacter(chars[i]);
4093 }
4094 for (; i < length; i++) {
4095 hasher.AddCharacterNoIndex(chars[i]);
4096 }
4097 }
4098 return hasher.GetHashField();
4099}
4100
4101
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004102bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004103 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004104 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4105 return false;
4106 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004107 return SlowAsArrayIndex(index);
4108}
4109
4110
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004111Object* JSReceiver::GetPrototype() {
4112 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004113}
4114
4115
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004116PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004117 return GetPropertyAttributeWithReceiver(this, key);
4118}
4119
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004120// TODO(504): this may be useful in other places too where JSGlobalProxy
4121// is used.
4122Object* JSObject::BypassGlobalProxy() {
4123 if (IsJSGlobalProxy()) {
4124 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004125 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004126 ASSERT(proto->IsJSGlobalObject());
4127 return proto;
4128 }
4129 return this;
4130}
4131
4132
4133bool JSObject::HasHiddenPropertiesObject() {
4134 ASSERT(!IsJSGlobalProxy());
4135 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004136 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004137 false) != ABSENT;
4138}
4139
4140
4141Object* JSObject::GetHiddenPropertiesObject() {
4142 ASSERT(!IsJSGlobalProxy());
4143 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004144 // You can't install a getter on a property indexed by the hidden symbol,
4145 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
4146 // object.
4147 Object* result =
4148 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004149 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00004150 &attributes)->ToObjectUnchecked();
4151 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004152}
4153
4154
lrn@chromium.org303ada72010-10-27 09:33:13 +00004155MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004156 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004157 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004158 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00004159 DONT_ENUM,
4160 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004161}
4162
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004163
4164bool JSObject::HasElement(uint32_t index) {
4165 return HasElementWithReceiver(this, index);
4166}
4167
4168
4169bool AccessorInfo::all_can_read() {
4170 return BooleanBit::get(flag(), kAllCanReadBit);
4171}
4172
4173
4174void AccessorInfo::set_all_can_read(bool value) {
4175 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4176}
4177
4178
4179bool AccessorInfo::all_can_write() {
4180 return BooleanBit::get(flag(), kAllCanWriteBit);
4181}
4182
4183
4184void AccessorInfo::set_all_can_write(bool value) {
4185 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4186}
4187
4188
ager@chromium.org870a0b62008-11-04 11:43:05 +00004189bool AccessorInfo::prohibits_overwriting() {
4190 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4191}
4192
4193
4194void AccessorInfo::set_prohibits_overwriting(bool value) {
4195 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4196}
4197
4198
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004199PropertyAttributes AccessorInfo::property_attributes() {
4200 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4201}
4202
4203
4204void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
4205 ASSERT(AttributesField::is_valid(attributes));
4206 int rest_value = flag()->value() & ~AttributesField::mask();
4207 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
4208}
4209
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004210
4211template<typename Shape, typename Key>
4212void Dictionary<Shape, Key>::SetEntry(int entry,
4213 Object* key,
4214 Object* value) {
4215 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4216}
4217
4218
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004219template<typename Shape, typename Key>
4220void Dictionary<Shape, Key>::SetEntry(int entry,
4221 Object* key,
4222 Object* value,
4223 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004224 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004225 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004226 AssertNoAllocation no_gc;
4227 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004228 FixedArray::set(index, key, mode);
4229 FixedArray::set(index+1, value, mode);
4230 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004231}
4232
4233
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004234bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4235 ASSERT(other->IsNumber());
4236 return key == static_cast<uint32_t>(other->Number());
4237}
4238
4239
4240uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4241 return ComputeIntegerHash(key);
4242}
4243
4244
4245uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4246 ASSERT(other->IsNumber());
4247 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4248}
4249
4250
4251MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4252 return Isolate::Current()->heap()->NumberFromUint32(key);
4253}
4254
4255
4256bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4257 // We know that all entries in a hash table had their hash keys created.
4258 // Use that knowledge to have fast failure.
4259 if (key->Hash() != String::cast(other)->Hash()) return false;
4260 return key->Equals(String::cast(other));
4261}
4262
4263
4264uint32_t StringDictionaryShape::Hash(String* key) {
4265 return key->Hash();
4266}
4267
4268
4269uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4270 return String::cast(other)->Hash();
4271}
4272
4273
4274MaybeObject* StringDictionaryShape::AsObject(String* key) {
4275 return key;
4276}
4277
4278
4279void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004280 // No write barrier is needed since empty_fixed_array is not in new space.
4281 // Please note this function is used during marking:
4282 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004283 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4284 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004285}
4286
4287
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004288void JSArray::EnsureSize(int required_size) {
4289 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004290 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004291 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4292 if (elts->length() < required_size) {
4293 // Doubling in size would be overkill, but leave some slack to avoid
4294 // constantly growing.
4295 Expand(required_size + (required_size >> 3));
4296 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004297 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004298 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4299 // Expand will allocate a new backing store in new space even if the size
4300 // we asked for isn't larger than what we had before.
4301 Expand(required_size);
4302 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004303}
4304
4305
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004306void JSArray::set_length(Smi* length) {
4307 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4308}
4309
4310
ager@chromium.org7c537e22008-10-16 08:43:32 +00004311void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004312 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004313 set_elements(storage);
4314}
4315
4316
lrn@chromium.org303ada72010-10-27 09:33:13 +00004317MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004318 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004319 return GetHeap()->CopyFixedArray(this);
4320}
4321
4322
4323Relocatable::Relocatable(Isolate* isolate) {
4324 ASSERT(isolate == Isolate::Current());
4325 isolate_ = isolate;
4326 prev_ = isolate->relocatable_top();
4327 isolate->set_relocatable_top(this);
4328}
4329
4330
4331Relocatable::~Relocatable() {
4332 ASSERT(isolate_ == Isolate::Current());
4333 ASSERT_EQ(isolate_->relocatable_top(), this);
4334 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004335}
4336
4337
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004338int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4339 return map->instance_size();
4340}
4341
4342
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004343void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004344 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004345 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004346}
4347
4348
4349template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004350void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004351 StaticVisitor::VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004352 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004353}
4354
4355
4356void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4357 typedef v8::String::ExternalAsciiStringResource Resource;
4358 v->VisitExternalAsciiString(
4359 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4360}
4361
4362
4363template<typename StaticVisitor>
4364void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4365 typedef v8::String::ExternalAsciiStringResource Resource;
4366 StaticVisitor::VisitExternalAsciiString(
4367 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4368}
4369
4370
4371void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4372 typedef v8::String::ExternalStringResource Resource;
4373 v->VisitExternalTwoByteString(
4374 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4375}
4376
4377
4378template<typename StaticVisitor>
4379void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4380 typedef v8::String::ExternalStringResource Resource;
4381 StaticVisitor::VisitExternalTwoByteString(
4382 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4383}
4384
4385#define SLOT_ADDR(obj, offset) \
4386 reinterpret_cast<Object**>((obj)->address() + offset)
4387
4388template<int start_offset, int end_offset, int size>
4389void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4390 HeapObject* obj,
4391 ObjectVisitor* v) {
4392 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4393}
4394
4395
4396template<int start_offset>
4397void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4398 int object_size,
4399 ObjectVisitor* v) {
4400 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4401}
4402
4403#undef SLOT_ADDR
4404
4405
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004406#undef CAST_ACCESSOR
4407#undef INT_ACCESSORS
4408#undef SMI_ACCESSORS
4409#undef ACCESSORS
4410#undef FIELD_ADDR
4411#undef READ_FIELD
4412#undef WRITE_FIELD
4413#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004414#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004415#undef READ_MEMADDR_FIELD
4416#undef WRITE_MEMADDR_FIELD
4417#undef READ_DOUBLE_FIELD
4418#undef WRITE_DOUBLE_FIELD
4419#undef READ_INT_FIELD
4420#undef WRITE_INT_FIELD
4421#undef READ_SHORT_FIELD
4422#undef WRITE_SHORT_FIELD
4423#undef READ_BYTE_FIELD
4424#undef WRITE_BYTE_FIELD
4425
4426
4427} } // namespace v8::internal
4428
4429#endif // V8_OBJECTS_INL_H_