blob: eb537c75a05b301c7a6aedfc5b31243c1259e89d [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
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00002063// TODO(1493): Investigate if it's possible to s/INT/SMI/ here (and
whesse@chromium.org7b260152011-06-20 15:33:18 +00002064// 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)
ager@chromium.org04921a82011-06-27 13:21:41 +00003235ACCESSORS(FunctionTemplateInfo, prototype_attributes, Smi,
3236 kPrototypeAttributesOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003237
3238ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003239ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3240 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003241
3242ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3243ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3244
3245ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3246
3247ACCESSORS(Script, source, Object, kSourceOffset)
3248ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003249ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003250ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3251ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003252ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003253ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003254ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003255ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003256ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003257ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003258ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003259ACCESSORS(Script, eval_from_instructions_offset, Smi,
3260 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003261
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003262#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003263ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3264ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3265ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3266ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3267
3268ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3269ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3270ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3271ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003272#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003273
3274ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003275ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3276ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003277ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3278 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003279ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003280ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3281ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003282ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003283ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3284 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003285
3286BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3287 kHiddenPrototypeBit)
3288BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3289BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3290 kNeedsAccessCheckBit)
3291BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3292 kIsExpressionBit)
3293BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3294 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003295BOOL_GETTER(SharedFunctionInfo,
3296 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003297 has_only_simple_this_property_assignments,
3298 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003299BOOL_ACCESSORS(SharedFunctionInfo,
3300 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003301 allows_lazy_compilation,
3302 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003303BOOL_ACCESSORS(SharedFunctionInfo,
3304 compiler_hints,
3305 uses_arguments,
3306 kUsesArguments)
3307BOOL_ACCESSORS(SharedFunctionInfo,
3308 compiler_hints,
3309 has_duplicate_parameters,
3310 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003311
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003312
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003313#if V8_HOST_ARCH_32_BIT
3314SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3315SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003316 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003317SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003318 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003319SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3320SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003321 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003322SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3323SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003324 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003325SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003326 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003327SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003328 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003329SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003330#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003331
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003332#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003333 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003334 int holder::name() { \
3335 int value = READ_INT_FIELD(this, offset); \
3336 ASSERT(kHeapObjectTag == 1); \
3337 ASSERT((value & kHeapObjectTag) == 0); \
3338 return value >> 1; \
3339 } \
3340 void holder::set_##name(int value) { \
3341 ASSERT(kHeapObjectTag == 1); \
3342 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3343 (value & 0xC0000000) == 0x000000000); \
3344 WRITE_INT_FIELD(this, \
3345 offset, \
3346 (value << 1) & ~kHeapObjectTag); \
3347 }
3348
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003349#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3350 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003351 INT_ACCESSORS(holder, name, offset)
3352
3353
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003354PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003355PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3356 formal_parameter_count,
3357 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003358
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003359PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3360 expected_nof_properties,
3361 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003362PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3363
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003364PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3365PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3366 start_position_and_type,
3367 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003368
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003369PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3370 function_token_position,
3371 kFunctionTokenPositionOffset)
3372PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3373 compiler_hints,
3374 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003375
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003376PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3377 this_property_assignments_count,
3378 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003379PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003380#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003381
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003382
3383int SharedFunctionInfo::construction_count() {
3384 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3385}
3386
3387
3388void SharedFunctionInfo::set_construction_count(int value) {
3389 ASSERT(0 <= value && value < 256);
3390 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3391}
3392
3393
whesse@chromium.org7b260152011-06-20 15:33:18 +00003394BOOL_ACCESSORS(SharedFunctionInfo,
3395 compiler_hints,
3396 live_objects_may_exist,
3397 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003398
3399
3400bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003401 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003402}
3403
3404
whesse@chromium.org7b260152011-06-20 15:33:18 +00003405BOOL_GETTER(SharedFunctionInfo,
3406 compiler_hints,
3407 optimization_disabled,
3408 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003409
3410
3411void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3412 set_compiler_hints(BooleanBit::set(compiler_hints(),
3413 kOptimizationDisabled,
3414 disable));
3415 // If disabling optimizations we reflect that in the code object so
3416 // it will not be counted as optimizable code.
3417 if ((code()->kind() == Code::FUNCTION) && disable) {
3418 code()->set_optimizable(false);
3419 }
3420}
3421
3422
whesse@chromium.org7b260152011-06-20 15:33:18 +00003423BOOL_ACCESSORS(SharedFunctionInfo,
3424 compiler_hints,
3425 strict_mode,
3426 kStrictModeFunction)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003427
3428
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003429bool SharedFunctionInfo::native() {
3430 return BooleanBit::get(compiler_hints(), kNative);
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003431}
3432
3433
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003434void SharedFunctionInfo::set_native(bool value) {
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003435 set_compiler_hints(BooleanBit::set(compiler_hints(),
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003436 kNative,
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003437 value));
3438}
3439
3440
whesse@chromium.org7b260152011-06-20 15:33:18 +00003441bool SharedFunctionInfo::bound() {
3442 return BooleanBit::get(compiler_hints(), kBoundFunction);
3443}
3444
3445
3446void SharedFunctionInfo::set_bound(bool value) {
3447 set_compiler_hints(BooleanBit::set(compiler_hints(),
3448 kBoundFunction,
3449 value));
3450}
3451
3452
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003453ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3454ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3455
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003456ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3457
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003458bool Script::HasValidSource() {
3459 Object* src = this->source();
3460 if (!src->IsString()) return true;
3461 String* src_str = String::cast(src);
3462 if (!StringShape(src_str).IsExternal()) return true;
3463 if (src_str->IsAsciiRepresentation()) {
3464 return ExternalAsciiString::cast(src)->resource() != NULL;
3465 } else if (src_str->IsTwoByteRepresentation()) {
3466 return ExternalTwoByteString::cast(src)->resource() != NULL;
3467 }
3468 return true;
3469}
3470
3471
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003472void SharedFunctionInfo::DontAdaptArguments() {
3473 ASSERT(code()->kind() == Code::BUILTIN);
3474 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3475}
3476
3477
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003478int SharedFunctionInfo::start_position() {
3479 return start_position_and_type() >> kStartPositionShift;
3480}
3481
3482
3483void SharedFunctionInfo::set_start_position(int start_position) {
3484 set_start_position_and_type((start_position << kStartPositionShift)
3485 | (start_position_and_type() & ~kStartPositionMask));
3486}
3487
3488
3489Code* SharedFunctionInfo::code() {
3490 return Code::cast(READ_FIELD(this, kCodeOffset));
3491}
3492
3493
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003494Code* SharedFunctionInfo::unchecked_code() {
3495 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3496}
3497
3498
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003499void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003500 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003501 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003502}
3503
3504
ager@chromium.orgb5737492010-07-15 09:29:43 +00003505SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3506 return reinterpret_cast<SerializedScopeInfo*>(
3507 READ_FIELD(this, kScopeInfoOffset));
3508}
3509
3510
3511void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3512 WriteBarrierMode mode) {
3513 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003514 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003515}
3516
3517
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003518Smi* SharedFunctionInfo::deopt_counter() {
3519 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3520}
3521
3522
3523void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3524 WRITE_FIELD(this, kDeoptCounterOffset, value);
3525}
3526
3527
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003528bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003529 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003530 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003531}
3532
3533
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003534bool SharedFunctionInfo::IsApiFunction() {
3535 return function_data()->IsFunctionTemplateInfo();
3536}
3537
3538
3539FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3540 ASSERT(IsApiFunction());
3541 return FunctionTemplateInfo::cast(function_data());
3542}
3543
3544
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003545bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003546 return function_data()->IsSmi();
3547}
3548
3549
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003550BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3551 ASSERT(HasBuiltinFunctionId());
3552 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003553}
3554
3555
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003556int SharedFunctionInfo::code_age() {
3557 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3558}
3559
3560
3561void SharedFunctionInfo::set_code_age(int code_age) {
3562 set_compiler_hints(compiler_hints() |
3563 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3564}
3565
3566
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003567bool SharedFunctionInfo::has_deoptimization_support() {
3568 Code* code = this->code();
3569 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3570}
3571
3572
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003573bool JSFunction::IsBuiltin() {
3574 return context()->global()->IsJSBuiltinsObject();
3575}
3576
3577
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003578bool JSFunction::NeedsArgumentsAdaption() {
3579 return shared()->formal_parameter_count() !=
3580 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3581}
3582
3583
3584bool JSFunction::IsOptimized() {
3585 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3586}
3587
3588
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003589bool JSFunction::IsOptimizable() {
3590 return code()->kind() == Code::FUNCTION && code()->optimizable();
3591}
3592
3593
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003594bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003595 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003596}
3597
3598
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003599Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003600 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003601}
3602
3603
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003604Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003605 return reinterpret_cast<Code*>(
3606 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003607}
3608
3609
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003610void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003611 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003612 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003613 Address entry = value->entry();
3614 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003615}
3616
3617
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003618void JSFunction::ReplaceCode(Code* code) {
3619 bool was_optimized = IsOptimized();
3620 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3621
3622 set_code(code);
3623
3624 // Add/remove the function from the list of optimized functions for this
3625 // context based on the state change.
3626 if (!was_optimized && is_optimized) {
3627 context()->global_context()->AddOptimizedFunction(this);
3628 }
3629 if (was_optimized && !is_optimized) {
3630 context()->global_context()->RemoveOptimizedFunction(this);
3631 }
3632}
3633
3634
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003635Context* JSFunction::context() {
3636 return Context::cast(READ_FIELD(this, kContextOffset));
3637}
3638
3639
3640Object* JSFunction::unchecked_context() {
3641 return READ_FIELD(this, kContextOffset);
3642}
3643
3644
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003645SharedFunctionInfo* JSFunction::unchecked_shared() {
3646 return reinterpret_cast<SharedFunctionInfo*>(
3647 READ_FIELD(this, kSharedFunctionInfoOffset));
3648}
3649
3650
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003651void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003652 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003653 WRITE_FIELD(this, kContextOffset, value);
3654 WRITE_BARRIER(this, kContextOffset);
3655}
3656
3657ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3658 kPrototypeOrInitialMapOffset)
3659
3660
3661Map* JSFunction::initial_map() {
3662 return Map::cast(prototype_or_initial_map());
3663}
3664
3665
3666void JSFunction::set_initial_map(Map* value) {
3667 set_prototype_or_initial_map(value);
3668}
3669
3670
3671bool JSFunction::has_initial_map() {
3672 return prototype_or_initial_map()->IsMap();
3673}
3674
3675
3676bool JSFunction::has_instance_prototype() {
3677 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3678}
3679
3680
3681bool JSFunction::has_prototype() {
3682 return map()->has_non_instance_prototype() || has_instance_prototype();
3683}
3684
3685
3686Object* JSFunction::instance_prototype() {
3687 ASSERT(has_instance_prototype());
3688 if (has_initial_map()) return initial_map()->prototype();
3689 // When there is no initial map and the prototype is a JSObject, the
3690 // initial map field is used for the prototype field.
3691 return prototype_or_initial_map();
3692}
3693
3694
3695Object* JSFunction::prototype() {
3696 ASSERT(has_prototype());
3697 // If the function's prototype property has been set to a non-JSObject
3698 // value, that value is stored in the constructor field of the map.
3699 if (map()->has_non_instance_prototype()) return map()->constructor();
3700 return instance_prototype();
3701}
3702
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003703bool JSFunction::should_have_prototype() {
3704 return map()->function_with_prototype();
3705}
3706
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003707
3708bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003709 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003710}
3711
3712
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003713int JSFunction::NumberOfLiterals() {
3714 return literals()->length();
3715}
3716
3717
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003718Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003719 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003720 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003721}
3722
3723
3724void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3725 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003726 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003727 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3728 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3729}
3730
3731
3732Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003733 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003734 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3735}
3736
3737
3738void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3739 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003740 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003741 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003742 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003743}
3744
3745
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003746ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
3747
3748
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003749Address Foreign::address() {
3750 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003751}
3752
3753
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003754void Foreign::set_address(Address value) {
3755 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003756}
3757
3758
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003759ACCESSORS(JSValue, value, Object, kValueOffset)
3760
3761
3762JSValue* JSValue::cast(Object* obj) {
3763 ASSERT(obj->IsJSValue());
3764 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3765 return reinterpret_cast<JSValue*>(obj);
3766}
3767
3768
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003769ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3770ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3771ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3772ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3773ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3774SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3775SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3776
3777
3778JSMessageObject* JSMessageObject::cast(Object* obj) {
3779 ASSERT(obj->IsJSMessageObject());
3780 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3781 return reinterpret_cast<JSMessageObject*>(obj);
3782}
3783
3784
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003785INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003786ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003787ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003788ACCESSORS(Code, next_code_flushing_candidate,
3789 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003790
3791
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003792byte* Code::instruction_start() {
3793 return FIELD_ADDR(this, kHeaderSize);
3794}
3795
3796
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003797byte* Code::instruction_end() {
3798 return instruction_start() + instruction_size();
3799}
3800
3801
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003802int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003803 return RoundUp(instruction_size(), kObjectAlignment);
3804}
3805
3806
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003807FixedArray* Code::unchecked_deoptimization_data() {
3808 return reinterpret_cast<FixedArray*>(
3809 READ_FIELD(this, kDeoptimizationDataOffset));
3810}
3811
3812
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003813ByteArray* Code::unchecked_relocation_info() {
3814 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003815}
3816
3817
3818byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003819 return unchecked_relocation_info()->GetDataStartAddress();
3820}
3821
3822
3823int Code::relocation_size() {
3824 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003825}
3826
3827
3828byte* Code::entry() {
3829 return instruction_start();
3830}
3831
3832
3833bool Code::contains(byte* pc) {
3834 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003835 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003836}
3837
3838
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003839ACCESSORS(JSArray, length, Object, kLengthOffset)
3840
3841
ager@chromium.org236ad962008-09-25 09:45:57 +00003842ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003843
3844
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003845JSRegExp::Type JSRegExp::TypeTag() {
3846 Object* data = this->data();
3847 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3848 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3849 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003850}
3851
3852
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003853JSRegExp::Type JSRegExp::TypeTagUnchecked() {
3854 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
3855 return static_cast<JSRegExp::Type>(smi->value());
3856}
3857
3858
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003859int JSRegExp::CaptureCount() {
3860 switch (TypeTag()) {
3861 case ATOM:
3862 return 0;
3863 case IRREGEXP:
3864 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3865 default:
3866 UNREACHABLE();
3867 return -1;
3868 }
3869}
3870
3871
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003872JSRegExp::Flags JSRegExp::GetFlags() {
3873 ASSERT(this->data()->IsFixedArray());
3874 Object* data = this->data();
3875 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3876 return Flags(smi->value());
3877}
3878
3879
3880String* JSRegExp::Pattern() {
3881 ASSERT(this->data()->IsFixedArray());
3882 Object* data = this->data();
3883 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3884 return pattern;
3885}
3886
3887
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003888Object* JSRegExp::DataAt(int index) {
3889 ASSERT(TypeTag() != NOT_COMPILED);
3890 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003891}
3892
3893
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003894Object* JSRegExp::DataAtUnchecked(int index) {
3895 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
3896 int offset = FixedArray::kHeaderSize + index * kPointerSize;
3897 return READ_FIELD(fa, offset);
3898}
3899
3900
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003901void JSRegExp::SetDataAt(int index, Object* value) {
3902 ASSERT(TypeTag() != NOT_COMPILED);
3903 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3904 FixedArray::cast(data())->set(index, value);
3905}
3906
3907
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003908void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
3909 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3910 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
3911 if (value->IsSmi()) {
3912 fa->set_unchecked(index, Smi::cast(value));
3913 } else {
3914 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
3915 }
3916}
3917
3918
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003919JSObject::ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003920 ElementsKind kind = map()->elements_kind();
3921 ASSERT((kind == FAST_ELEMENTS &&
3922 (elements()->map() == GetHeap()->fixed_array_map() ||
3923 elements()->map() == GetHeap()->fixed_cow_array_map())) ||
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003924 (kind == FAST_DOUBLE_ELEMENTS &&
3925 elements()->IsFixedDoubleArray()) ||
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003926 (kind == DICTIONARY_ELEMENTS &&
3927 elements()->IsFixedArray() &&
3928 elements()->IsDictionary()) ||
3929 (kind > DICTIONARY_ELEMENTS));
3930 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003931}
3932
3933
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003934bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003935 return GetElementsKind() == FAST_ELEMENTS;
3936}
3937
3938
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003939bool JSObject::HasFastDoubleElements() {
3940 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
3941}
3942
3943
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003944bool JSObject::HasDictionaryElements() {
3945 return GetElementsKind() == DICTIONARY_ELEMENTS;
3946}
3947
3948
ager@chromium.org3811b432009-10-28 14:53:37 +00003949bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003950 HeapObject* array = elements();
3951 ASSERT(array != NULL);
3952 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00003953}
3954
3955
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003956#define EXTERNAL_ELEMENTS_CHECK(name, type) \
3957bool JSObject::HasExternal##name##Elements() { \
3958 HeapObject* array = elements(); \
3959 ASSERT(array != NULL); \
3960 if (!array->IsHeapObject()) \
3961 return false; \
3962 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00003963}
3964
3965
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003966EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
3967EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
3968EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
3969EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
3970 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
3971EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
3972EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
3973 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
3974EXTERNAL_ELEMENTS_CHECK(Float,
3975 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003976EXTERNAL_ELEMENTS_CHECK(Double,
3977 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003978EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00003979
3980
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003981bool JSObject::HasNamedInterceptor() {
3982 return map()->has_named_interceptor();
3983}
3984
3985
3986bool JSObject::HasIndexedInterceptor() {
3987 return map()->has_indexed_interceptor();
3988}
3989
3990
ager@chromium.org5c838252010-02-19 08:53:10 +00003991bool JSObject::AllowsSetElementsLength() {
3992 bool result = elements()->IsFixedArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003993 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00003994 return result;
3995}
3996
3997
lrn@chromium.org303ada72010-10-27 09:33:13 +00003998MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003999 ASSERT(HasFastElements());
4000 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004001 Isolate* isolate = GetIsolate();
4002 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004003 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004004 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4005 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004006 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4007 return maybe_writable_elems;
4008 }
4009 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004010 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004011 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004012 return writable_elems;
4013}
4014
4015
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004016StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004017 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004018 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004019}
4020
4021
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004022NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004023 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004024 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004025}
4026
4027
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004028bool String::IsHashFieldComputed(uint32_t field) {
4029 return (field & kHashNotComputedMask) == 0;
4030}
4031
4032
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004033bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004034 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004035}
4036
4037
4038uint32_t String::Hash() {
4039 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004040 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004041 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004042 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004043 return ComputeAndSetHash();
4044}
4045
4046
ager@chromium.org7c537e22008-10-16 08:43:32 +00004047StringHasher::StringHasher(int length)
4048 : length_(length),
4049 raw_running_hash_(0),
4050 array_index_(0),
4051 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4052 is_first_char_(true),
4053 is_valid_(true) { }
4054
4055
4056bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004057 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004058}
4059
4060
4061void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004062 // Use the Jenkins one-at-a-time hash function to update the hash
4063 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004064 raw_running_hash_ += c;
4065 raw_running_hash_ += (raw_running_hash_ << 10);
4066 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004067 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004068 if (is_array_index_) {
4069 if (c < '0' || c > '9') {
4070 is_array_index_ = false;
4071 } else {
4072 int d = c - '0';
4073 if (is_first_char_) {
4074 is_first_char_ = false;
4075 if (c == '0' && length_ > 1) {
4076 is_array_index_ = false;
4077 return;
4078 }
4079 }
4080 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4081 is_array_index_ = false;
4082 } else {
4083 array_index_ = array_index_ * 10 + d;
4084 }
4085 }
4086 }
4087}
4088
4089
4090void StringHasher::AddCharacterNoIndex(uc32 c) {
4091 ASSERT(!is_array_index());
4092 raw_running_hash_ += c;
4093 raw_running_hash_ += (raw_running_hash_ << 10);
4094 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4095}
4096
4097
4098uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004099 // Get the calculated raw hash value and do some more bit ops to distribute
4100 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004101 uint32_t result = raw_running_hash_;
4102 result += (result << 3);
4103 result ^= (result >> 11);
4104 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004105 if (result == 0) {
4106 result = 27;
4107 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004108 return result;
4109}
4110
4111
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004112template <typename schar>
4113uint32_t HashSequentialString(const schar* chars, int length) {
4114 StringHasher hasher(length);
4115 if (!hasher.has_trivial_hash()) {
4116 int i;
4117 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4118 hasher.AddCharacter(chars[i]);
4119 }
4120 for (; i < length; i++) {
4121 hasher.AddCharacterNoIndex(chars[i]);
4122 }
4123 }
4124 return hasher.GetHashField();
4125}
4126
4127
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004128bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004129 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004130 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4131 return false;
4132 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004133 return SlowAsArrayIndex(index);
4134}
4135
4136
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004137Object* JSReceiver::GetPrototype() {
4138 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004139}
4140
4141
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004142PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004143 return GetPropertyAttributeWithReceiver(this, key);
4144}
4145
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004146// TODO(504): this may be useful in other places too where JSGlobalProxy
4147// is used.
4148Object* JSObject::BypassGlobalProxy() {
4149 if (IsJSGlobalProxy()) {
4150 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004151 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004152 ASSERT(proto->IsJSGlobalObject());
4153 return proto;
4154 }
4155 return this;
4156}
4157
4158
4159bool JSObject::HasHiddenPropertiesObject() {
4160 ASSERT(!IsJSGlobalProxy());
4161 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004162 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004163 false) != ABSENT;
4164}
4165
4166
4167Object* JSObject::GetHiddenPropertiesObject() {
4168 ASSERT(!IsJSGlobalProxy());
4169 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004170 // You can't install a getter on a property indexed by the hidden symbol,
4171 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
4172 // object.
4173 Object* result =
4174 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004175 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00004176 &attributes)->ToObjectUnchecked();
4177 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004178}
4179
4180
lrn@chromium.org303ada72010-10-27 09:33:13 +00004181MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004182 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004183 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004184 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00004185 DONT_ENUM,
4186 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004187}
4188
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004189
4190bool JSObject::HasElement(uint32_t index) {
4191 return HasElementWithReceiver(this, index);
4192}
4193
4194
4195bool AccessorInfo::all_can_read() {
4196 return BooleanBit::get(flag(), kAllCanReadBit);
4197}
4198
4199
4200void AccessorInfo::set_all_can_read(bool value) {
4201 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4202}
4203
4204
4205bool AccessorInfo::all_can_write() {
4206 return BooleanBit::get(flag(), kAllCanWriteBit);
4207}
4208
4209
4210void AccessorInfo::set_all_can_write(bool value) {
4211 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4212}
4213
4214
ager@chromium.org870a0b62008-11-04 11:43:05 +00004215bool AccessorInfo::prohibits_overwriting() {
4216 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4217}
4218
4219
4220void AccessorInfo::set_prohibits_overwriting(bool value) {
4221 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4222}
4223
4224
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004225PropertyAttributes AccessorInfo::property_attributes() {
4226 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4227}
4228
4229
4230void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
4231 ASSERT(AttributesField::is_valid(attributes));
4232 int rest_value = flag()->value() & ~AttributesField::mask();
4233 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
4234}
4235
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004236
4237template<typename Shape, typename Key>
4238void Dictionary<Shape, Key>::SetEntry(int entry,
4239 Object* key,
4240 Object* value) {
4241 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4242}
4243
4244
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004245template<typename Shape, typename Key>
4246void Dictionary<Shape, Key>::SetEntry(int entry,
4247 Object* key,
4248 Object* value,
4249 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004250 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004251 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004252 AssertNoAllocation no_gc;
4253 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004254 FixedArray::set(index, key, mode);
4255 FixedArray::set(index+1, value, mode);
4256 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004257}
4258
4259
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004260bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4261 ASSERT(other->IsNumber());
4262 return key == static_cast<uint32_t>(other->Number());
4263}
4264
4265
4266uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4267 return ComputeIntegerHash(key);
4268}
4269
4270
4271uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4272 ASSERT(other->IsNumber());
4273 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4274}
4275
4276
4277MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4278 return Isolate::Current()->heap()->NumberFromUint32(key);
4279}
4280
4281
4282bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4283 // We know that all entries in a hash table had their hash keys created.
4284 // Use that knowledge to have fast failure.
4285 if (key->Hash() != String::cast(other)->Hash()) return false;
4286 return key->Equals(String::cast(other));
4287}
4288
4289
4290uint32_t StringDictionaryShape::Hash(String* key) {
4291 return key->Hash();
4292}
4293
4294
4295uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4296 return String::cast(other)->Hash();
4297}
4298
4299
4300MaybeObject* StringDictionaryShape::AsObject(String* key) {
4301 return key;
4302}
4303
4304
4305void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004306 // No write barrier is needed since empty_fixed_array is not in new space.
4307 // Please note this function is used during marking:
4308 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004309 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4310 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004311}
4312
4313
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004314void JSArray::EnsureSize(int required_size) {
4315 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004316 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004317 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4318 if (elts->length() < required_size) {
4319 // Doubling in size would be overkill, but leave some slack to avoid
4320 // constantly growing.
4321 Expand(required_size + (required_size >> 3));
4322 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004323 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004324 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4325 // Expand will allocate a new backing store in new space even if the size
4326 // we asked for isn't larger than what we had before.
4327 Expand(required_size);
4328 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004329}
4330
4331
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004332void JSArray::set_length(Smi* length) {
4333 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4334}
4335
4336
ager@chromium.org7c537e22008-10-16 08:43:32 +00004337void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004338 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004339 set_elements(storage);
4340}
4341
4342
lrn@chromium.org303ada72010-10-27 09:33:13 +00004343MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004344 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004345 return GetHeap()->CopyFixedArray(this);
4346}
4347
4348
4349Relocatable::Relocatable(Isolate* isolate) {
4350 ASSERT(isolate == Isolate::Current());
4351 isolate_ = isolate;
4352 prev_ = isolate->relocatable_top();
4353 isolate->set_relocatable_top(this);
4354}
4355
4356
4357Relocatable::~Relocatable() {
4358 ASSERT(isolate_ == Isolate::Current());
4359 ASSERT_EQ(isolate_->relocatable_top(), this);
4360 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004361}
4362
4363
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004364int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4365 return map->instance_size();
4366}
4367
4368
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004369void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004370 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004371 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004372}
4373
4374
4375template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004376void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004377 StaticVisitor::VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004378 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004379}
4380
4381
4382void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4383 typedef v8::String::ExternalAsciiStringResource Resource;
4384 v->VisitExternalAsciiString(
4385 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4386}
4387
4388
4389template<typename StaticVisitor>
4390void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4391 typedef v8::String::ExternalAsciiStringResource Resource;
4392 StaticVisitor::VisitExternalAsciiString(
4393 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4394}
4395
4396
4397void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4398 typedef v8::String::ExternalStringResource Resource;
4399 v->VisitExternalTwoByteString(
4400 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4401}
4402
4403
4404template<typename StaticVisitor>
4405void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4406 typedef v8::String::ExternalStringResource Resource;
4407 StaticVisitor::VisitExternalTwoByteString(
4408 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4409}
4410
4411#define SLOT_ADDR(obj, offset) \
4412 reinterpret_cast<Object**>((obj)->address() + offset)
4413
4414template<int start_offset, int end_offset, int size>
4415void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4416 HeapObject* obj,
4417 ObjectVisitor* v) {
4418 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4419}
4420
4421
4422template<int start_offset>
4423void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4424 int object_size,
4425 ObjectVisitor* v) {
4426 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4427}
4428
4429#undef SLOT_ADDR
4430
4431
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004432#undef CAST_ACCESSOR
4433#undef INT_ACCESSORS
4434#undef SMI_ACCESSORS
4435#undef ACCESSORS
4436#undef FIELD_ADDR
4437#undef READ_FIELD
4438#undef WRITE_FIELD
4439#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004440#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004441#undef READ_MEMADDR_FIELD
4442#undef WRITE_MEMADDR_FIELD
4443#undef READ_DOUBLE_FIELD
4444#undef WRITE_DOUBLE_FIELD
4445#undef READ_INT_FIELD
4446#undef WRITE_INT_FIELD
4447#undef READ_SHORT_FIELD
4448#undef WRITE_SHORT_FIELD
4449#undef READ_BYTE_FIELD
4450#undef WRITE_BYTE_FIELD
4451
4452
4453} } // namespace v8::internal
4454
4455#endif // V8_OBJECTS_INL_H_