blob: fdc5102049fcc2fd7b9119c9824218203af77053 [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.org84bcc552011-07-18 09:50:57 +00001613inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1614 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1615}
1616
1617
1618inline double FixedDoubleArray::hole_nan_as_double() {
1619 return BitCast<double, uint64_t>(kHoleNanInt64);
1620}
1621
1622
1623inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1624 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1625 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1626 return OS::nan_value();
1627}
1628
1629
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001630double FixedDoubleArray::get(int index) {
1631 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1632 map() != HEAP->fixed_array_map());
1633 ASSERT(index >= 0 && index < this->length());
1634 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1635 ASSERT(!is_the_hole_nan(result));
1636 return result;
1637}
1638
1639
1640void FixedDoubleArray::set(int index, double value) {
1641 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1642 map() != HEAP->fixed_array_map());
1643 int offset = kHeaderSize + index * kDoubleSize;
1644 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1645 WRITE_DOUBLE_FIELD(this, offset, value);
1646}
1647
1648
1649void FixedDoubleArray::set_the_hole(int index) {
1650 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1651 map() != HEAP->fixed_array_map());
1652 int offset = kHeaderSize + index * kDoubleSize;
1653 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1654}
1655
1656
1657bool FixedDoubleArray::is_the_hole(int index) {
1658 int offset = kHeaderSize + index * kDoubleSize;
1659 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1660}
1661
1662
1663void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1664 int old_length = from->length();
1665 ASSERT(old_length < length());
1666 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1667 FIELD_ADDR(from, kHeaderSize),
1668 old_length * kDoubleSize);
1669 int offset = kHeaderSize + old_length * kDoubleSize;
1670 for (int current = from->length(); current < length(); ++current) {
1671 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1672 offset += kDoubleSize;
1673 }
1674}
1675
1676
1677void FixedDoubleArray::Initialize(FixedArray* from) {
1678 int old_length = from->length();
1679 ASSERT(old_length < length());
1680 for (int i = 0; i < old_length; i++) {
1681 Object* hole_or_object = from->get(i);
1682 if (hole_or_object->IsTheHole()) {
1683 set_the_hole(i);
1684 } else {
1685 set(i, hole_or_object->Number());
1686 }
1687 }
1688 int offset = kHeaderSize + old_length * kDoubleSize;
1689 for (int current = from->length(); current < length(); ++current) {
1690 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1691 offset += kDoubleSize;
1692 }
1693}
1694
1695
1696void FixedDoubleArray::Initialize(NumberDictionary* from) {
1697 int offset = kHeaderSize;
1698 for (int current = 0; current < length(); ++current) {
1699 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1700 offset += kDoubleSize;
1701 }
1702 for (int i = 0; i < from->Capacity(); i++) {
1703 Object* key = from->KeyAt(i);
1704 if (key->IsNumber()) {
1705 uint32_t entry = static_cast<uint32_t>(key->Number());
1706 set(entry, from->ValueAt(i)->Number());
1707 }
1708 }
1709}
1710
1711
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001712WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001713 if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001714 return UPDATE_WRITE_BARRIER;
1715}
1716
1717
1718void FixedArray::set(int index,
1719 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001720 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001721 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001722 ASSERT(index >= 0 && index < this->length());
1723 int offset = kHeaderSize + index * kPointerSize;
1724 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001725 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001726}
1727
1728
1729void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001730 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001731 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001732 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001733 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1734}
1735
1736
1737void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001738 ASSERT(map() != HEAP->fixed_cow_array_map());
1739 set_undefined(GetHeap(), index);
1740}
1741
1742
1743void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001744 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001745 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001746 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001747 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001748}
1749
1750
ager@chromium.org236ad962008-09-25 09:45:57 +00001751void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001752 set_null(GetHeap(), index);
1753}
1754
1755
1756void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001757 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001758 ASSERT(!heap->InNewSpace(heap->null_value()));
1759 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001760}
1761
1762
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001763void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001764 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001765 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001766 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1767 WRITE_FIELD(this,
1768 kHeaderSize + index * kPointerSize,
1769 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001770}
1771
1772
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001773void FixedArray::set_unchecked(int index, Smi* value) {
1774 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1775 int offset = kHeaderSize + index * kPointerSize;
1776 WRITE_FIELD(this, offset, value);
1777}
1778
1779
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001780void FixedArray::set_unchecked(Heap* heap,
1781 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001782 Object* value,
1783 WriteBarrierMode mode) {
1784 int offset = kHeaderSize + index * kPointerSize;
1785 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001786 CONDITIONAL_WRITE_BARRIER(heap, this, offset, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001787}
1788
1789
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001790void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001791 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001792 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1793 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001794}
1795
1796
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001797Object** FixedArray::data_start() {
1798 return HeapObject::RawField(this, kHeaderSize);
1799}
1800
1801
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001802bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001803 ASSERT(this->IsSmi() ||
1804 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001805 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001806 return this->IsSmi() || length() <= kFirstIndex;
1807}
1808
1809
1810int DescriptorArray::bit_field3_storage() {
1811 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1812 return Smi::cast(storage)->value();
1813}
1814
1815void DescriptorArray::set_bit_field3_storage(int value) {
1816 ASSERT(!IsEmpty());
1817 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001818}
1819
1820
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001821void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1822 Object* tmp = array->get(first);
1823 fast_set(array, first, array->get(second));
1824 fast_set(array, second, tmp);
1825}
1826
1827
1828int DescriptorArray::Search(String* name) {
1829 SLOW_ASSERT(IsSortedNoDuplicates());
1830
1831 // Check for empty descriptor array.
1832 int nof = number_of_descriptors();
1833 if (nof == 0) return kNotFound;
1834
1835 // Fast case: do linear search for small arrays.
1836 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001837 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001838 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001839 }
1840
1841 // Slow case: perform binary search.
1842 return BinarySearch(name, 0, nof - 1);
1843}
1844
1845
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001846int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001847 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001848 if (number == DescriptorLookupCache::kAbsent) {
1849 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001850 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001851 }
1852 return number;
1853}
1854
1855
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001856String* DescriptorArray::GetKey(int descriptor_number) {
1857 ASSERT(descriptor_number < number_of_descriptors());
1858 return String::cast(get(ToKeyIndex(descriptor_number)));
1859}
1860
1861
1862Object* DescriptorArray::GetValue(int descriptor_number) {
1863 ASSERT(descriptor_number < number_of_descriptors());
1864 return GetContentArray()->get(ToValueIndex(descriptor_number));
1865}
1866
1867
1868Smi* DescriptorArray::GetDetails(int descriptor_number) {
1869 ASSERT(descriptor_number < number_of_descriptors());
1870 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1871}
1872
1873
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001874PropertyType DescriptorArray::GetType(int descriptor_number) {
1875 ASSERT(descriptor_number < number_of_descriptors());
1876 return PropertyDetails(GetDetails(descriptor_number)).type();
1877}
1878
1879
1880int DescriptorArray::GetFieldIndex(int descriptor_number) {
1881 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1882}
1883
1884
1885JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1886 return JSFunction::cast(GetValue(descriptor_number));
1887}
1888
1889
1890Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1891 ASSERT(GetType(descriptor_number) == CALLBACKS);
1892 return GetValue(descriptor_number);
1893}
1894
1895
1896AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1897 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001898 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
1899 return reinterpret_cast<AccessorDescriptor*>(p->address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001900}
1901
1902
1903bool DescriptorArray::IsProperty(int descriptor_number) {
1904 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1905}
1906
1907
1908bool DescriptorArray::IsTransition(int descriptor_number) {
1909 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001910 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
1911 t == EXTERNAL_ARRAY_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001912}
1913
1914
1915bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1916 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1917}
1918
1919
1920bool DescriptorArray::IsDontEnum(int descriptor_number) {
1921 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1922}
1923
1924
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001925void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1926 desc->Init(GetKey(descriptor_number),
1927 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001928 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001929}
1930
1931
1932void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1933 // Range check.
1934 ASSERT(descriptor_number < number_of_descriptors());
1935
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001936 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001937 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1938 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001939
1940 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1941 FixedArray* content_array = GetContentArray();
1942 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1943 fast_set(content_array, ToDetailsIndex(descriptor_number),
1944 desc->GetDetails().AsSmi());
1945}
1946
1947
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001948void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1949 Descriptor desc;
1950 src->Get(src_index, &desc);
1951 Set(index, &desc);
1952}
1953
1954
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001955void DescriptorArray::Swap(int first, int second) {
1956 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1957 FixedArray* content_array = GetContentArray();
1958 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1959 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1960}
1961
1962
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001963template<typename Shape, typename Key>
1964int HashTable<Shape, Key>::FindEntry(Key key) {
1965 return FindEntry(GetIsolate(), key);
1966}
1967
1968
1969// Find entry for key otherwise return kNotFound.
1970template<typename Shape, typename Key>
1971int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
1972 uint32_t capacity = Capacity();
1973 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
1974 uint32_t count = 1;
1975 // EnsureCapacity will guarantee the hash table is never full.
1976 while (true) {
1977 Object* element = KeyAt(entry);
1978 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
1979 if (element != isolate->heap()->null_value() &&
1980 Shape::IsMatch(key, element)) return entry;
1981 entry = NextProbe(entry, count++, capacity);
1982 }
1983 return kNotFound;
1984}
1985
1986
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001987bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001988 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001989 if (!max_index_object->IsSmi()) return false;
1990 return 0 !=
1991 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1992}
1993
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001994uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001995 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001996 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001997 if (!max_index_object->IsSmi()) return 0;
1998 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1999 return value >> kRequiresSlowElementsTagSize;
2000}
2001
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002002void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002003 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002004}
2005
2006
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002007// ------------------------------------
2008// Cast operations
2009
2010
2011CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002012CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002013CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002014CAST_ACCESSOR(DeoptimizationInputData)
2015CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002016CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002017CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002018CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002019CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002020CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002021CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002022CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002023CAST_ACCESSOR(String)
2024CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002025CAST_ACCESSOR(SeqAsciiString)
2026CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002027CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002028CAST_ACCESSOR(ExternalString)
2029CAST_ACCESSOR(ExternalAsciiString)
2030CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002031CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002032CAST_ACCESSOR(JSObject)
2033CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002034CAST_ACCESSOR(HeapObject)
2035CAST_ACCESSOR(HeapNumber)
2036CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002037CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002038CAST_ACCESSOR(SharedFunctionInfo)
2039CAST_ACCESSOR(Map)
2040CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002041CAST_ACCESSOR(GlobalObject)
2042CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002043CAST_ACCESSOR(JSGlobalObject)
2044CAST_ACCESSOR(JSBuiltinsObject)
2045CAST_ACCESSOR(Code)
2046CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002047CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002048CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002049CAST_ACCESSOR(JSFunctionProxy)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002050CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002051CAST_ACCESSOR(ByteArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00002052CAST_ACCESSOR(ExternalArray)
2053CAST_ACCESSOR(ExternalByteArray)
2054CAST_ACCESSOR(ExternalUnsignedByteArray)
2055CAST_ACCESSOR(ExternalShortArray)
2056CAST_ACCESSOR(ExternalUnsignedShortArray)
2057CAST_ACCESSOR(ExternalIntArray)
2058CAST_ACCESSOR(ExternalUnsignedIntArray)
2059CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002060CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002061CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002062CAST_ACCESSOR(Struct)
2063
2064
2065#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2066 STRUCT_LIST(MAKE_STRUCT_CAST)
2067#undef MAKE_STRUCT_CAST
2068
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002069
2070template <typename Shape, typename Key>
2071HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002072 ASSERT(obj->IsHashTable());
2073 return reinterpret_cast<HashTable*>(obj);
2074}
2075
2076
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002077SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002078SMI_ACCESSORS(ByteArray, length, kLengthOffset)
2079
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00002080// TODO(1493): Investigate if it's possible to s/INT/SMI/ here (and
whesse@chromium.org7b260152011-06-20 15:33:18 +00002081// subsequently unify H{Fixed,External}ArrayLength).
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002082INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002083
2084
ager@chromium.orgac091b72010-05-05 07:34:42 +00002085SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002086
2087
2088uint32_t String::hash_field() {
2089 return READ_UINT32_FIELD(this, kHashFieldOffset);
2090}
2091
2092
2093void String::set_hash_field(uint32_t value) {
2094 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002095#if V8_HOST_ARCH_64_BIT
2096 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2097#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002098}
2099
2100
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002101bool String::Equals(String* other) {
2102 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002103 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2104 return false;
2105 }
2106 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002107}
2108
2109
lrn@chromium.org303ada72010-10-27 09:33:13 +00002110MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002111 if (!StringShape(this).IsCons()) return this;
2112 ConsString* cons = ConsString::cast(this);
2113 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002114 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002115}
2116
2117
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002118String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002119 MaybeObject* flat = TryFlatten(pretenure);
2120 Object* successfully_flattened;
2121 if (flat->ToObject(&successfully_flattened)) {
2122 return String::cast(successfully_flattened);
2123 }
2124 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002125}
2126
2127
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002128uint16_t String::Get(int index) {
2129 ASSERT(index >= 0 && index < length());
2130 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002131 case kSeqStringTag | kAsciiStringTag:
2132 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2133 case kSeqStringTag | kTwoByteStringTag:
2134 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2135 case kConsStringTag | kAsciiStringTag:
2136 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002137 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002138 case kExternalStringTag | kAsciiStringTag:
2139 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2140 case kExternalStringTag | kTwoByteStringTag:
2141 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002142 default:
2143 break;
2144 }
2145
2146 UNREACHABLE();
2147 return 0;
2148}
2149
2150
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002151void String::Set(int index, uint16_t value) {
2152 ASSERT(index >= 0 && index < length());
2153 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002154
ager@chromium.org5ec48922009-05-05 07:25:34 +00002155 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002156 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2157 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002158}
2159
2160
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002161bool String::IsFlat() {
2162 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002163 case kConsStringTag: {
2164 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002165 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00002166 return second->length() == 0;
2167 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002168 default:
2169 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002170 }
2171}
2172
2173
ager@chromium.org7c537e22008-10-16 08:43:32 +00002174uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002175 ASSERT(index >= 0 && index < length());
2176 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2177}
2178
2179
ager@chromium.org7c537e22008-10-16 08:43:32 +00002180void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002181 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2182 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2183 static_cast<byte>(value));
2184}
2185
2186
ager@chromium.org7c537e22008-10-16 08:43:32 +00002187Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002188 return FIELD_ADDR(this, kHeaderSize);
2189}
2190
2191
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002192char* SeqAsciiString::GetChars() {
2193 return reinterpret_cast<char*>(GetCharsAddress());
2194}
2195
2196
ager@chromium.org7c537e22008-10-16 08:43:32 +00002197Address SeqTwoByteString::GetCharsAddress() {
2198 return FIELD_ADDR(this, kHeaderSize);
2199}
2200
2201
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002202uc16* SeqTwoByteString::GetChars() {
2203 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2204}
2205
2206
ager@chromium.org7c537e22008-10-16 08:43:32 +00002207uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002208 ASSERT(index >= 0 && index < length());
2209 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2210}
2211
2212
ager@chromium.org7c537e22008-10-16 08:43:32 +00002213void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002214 ASSERT(index >= 0 && index < length());
2215 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2216}
2217
2218
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002219int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002220 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002221}
2222
2223
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002224int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002225 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002226}
2227
2228
ager@chromium.org870a0b62008-11-04 11:43:05 +00002229String* ConsString::first() {
2230 return String::cast(READ_FIELD(this, kFirstOffset));
2231}
2232
2233
2234Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002235 return READ_FIELD(this, kFirstOffset);
2236}
2237
2238
ager@chromium.org870a0b62008-11-04 11:43:05 +00002239void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002240 WRITE_FIELD(this, kFirstOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002241 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002242}
2243
2244
ager@chromium.org870a0b62008-11-04 11:43:05 +00002245String* ConsString::second() {
2246 return String::cast(READ_FIELD(this, kSecondOffset));
2247}
2248
2249
2250Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002251 return READ_FIELD(this, kSecondOffset);
2252}
2253
2254
ager@chromium.org870a0b62008-11-04 11:43:05 +00002255void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002256 WRITE_FIELD(this, kSecondOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002257 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002258}
2259
2260
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002261ExternalAsciiString::Resource* ExternalAsciiString::resource() {
2262 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2263}
2264
2265
2266void ExternalAsciiString::set_resource(
2267 ExternalAsciiString::Resource* resource) {
2268 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2269}
2270
2271
2272ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
2273 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2274}
2275
2276
2277void ExternalTwoByteString::set_resource(
2278 ExternalTwoByteString::Resource* resource) {
2279 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2280}
2281
2282
ager@chromium.orgac091b72010-05-05 07:34:42 +00002283void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002284 set_finger_index(kEntriesIndex);
2285 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002286}
2287
2288
2289void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002290 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002291 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002292 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002293 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002294 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002295 MakeZeroSize();
2296}
2297
2298
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002299int JSFunctionResultCache::size() {
2300 return Smi::cast(get(kCacheSizeIndex))->value();
2301}
2302
2303
2304void JSFunctionResultCache::set_size(int size) {
2305 set(kCacheSizeIndex, Smi::FromInt(size));
2306}
2307
2308
2309int JSFunctionResultCache::finger_index() {
2310 return Smi::cast(get(kFingerIndex))->value();
2311}
2312
2313
2314void JSFunctionResultCache::set_finger_index(int finger_index) {
2315 set(kFingerIndex, Smi::FromInt(finger_index));
2316}
2317
2318
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002319byte ByteArray::get(int index) {
2320 ASSERT(index >= 0 && index < this->length());
2321 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2322}
2323
2324
2325void ByteArray::set(int index, byte value) {
2326 ASSERT(index >= 0 && index < this->length());
2327 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2328}
2329
2330
2331int ByteArray::get_int(int index) {
2332 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2333 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2334}
2335
2336
2337ByteArray* ByteArray::FromDataStartAddress(Address address) {
2338 ASSERT_TAG_ALIGNED(address);
2339 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2340}
2341
2342
2343Address ByteArray::GetDataStartAddress() {
2344 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2345}
2346
2347
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002348uint8_t* ExternalPixelArray::external_pixel_pointer() {
2349 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002350}
2351
2352
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002353uint8_t ExternalPixelArray::get(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002354 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002355 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002356 return ptr[index];
2357}
2358
2359
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002360void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002361 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002362 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002363 ptr[index] = value;
2364}
2365
2366
ager@chromium.org3811b432009-10-28 14:53:37 +00002367void* ExternalArray::external_pointer() {
2368 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2369 return reinterpret_cast<void*>(ptr);
2370}
2371
2372
2373void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2374 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2375 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2376}
2377
2378
2379int8_t ExternalByteArray::get(int index) {
2380 ASSERT((index >= 0) && (index < this->length()));
2381 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2382 return ptr[index];
2383}
2384
2385
2386void ExternalByteArray::set(int index, int8_t value) {
2387 ASSERT((index >= 0) && (index < this->length()));
2388 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2389 ptr[index] = value;
2390}
2391
2392
2393uint8_t ExternalUnsignedByteArray::get(int index) {
2394 ASSERT((index >= 0) && (index < this->length()));
2395 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2396 return ptr[index];
2397}
2398
2399
2400void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2401 ASSERT((index >= 0) && (index < this->length()));
2402 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2403 ptr[index] = value;
2404}
2405
2406
2407int16_t ExternalShortArray::get(int index) {
2408 ASSERT((index >= 0) && (index < this->length()));
2409 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2410 return ptr[index];
2411}
2412
2413
2414void ExternalShortArray::set(int index, int16_t value) {
2415 ASSERT((index >= 0) && (index < this->length()));
2416 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2417 ptr[index] = value;
2418}
2419
2420
2421uint16_t ExternalUnsignedShortArray::get(int index) {
2422 ASSERT((index >= 0) && (index < this->length()));
2423 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2424 return ptr[index];
2425}
2426
2427
2428void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2429 ASSERT((index >= 0) && (index < this->length()));
2430 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2431 ptr[index] = value;
2432}
2433
2434
2435int32_t ExternalIntArray::get(int index) {
2436 ASSERT((index >= 0) && (index < this->length()));
2437 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2438 return ptr[index];
2439}
2440
2441
2442void ExternalIntArray::set(int index, int32_t value) {
2443 ASSERT((index >= 0) && (index < this->length()));
2444 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2445 ptr[index] = value;
2446}
2447
2448
2449uint32_t ExternalUnsignedIntArray::get(int index) {
2450 ASSERT((index >= 0) && (index < this->length()));
2451 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2452 return ptr[index];
2453}
2454
2455
2456void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2457 ASSERT((index >= 0) && (index < this->length()));
2458 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2459 ptr[index] = value;
2460}
2461
2462
2463float ExternalFloatArray::get(int index) {
2464 ASSERT((index >= 0) && (index < this->length()));
2465 float* ptr = static_cast<float*>(external_pointer());
2466 return ptr[index];
2467}
2468
2469
2470void ExternalFloatArray::set(int index, float value) {
2471 ASSERT((index >= 0) && (index < this->length()));
2472 float* ptr = static_cast<float*>(external_pointer());
2473 ptr[index] = value;
2474}
2475
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002476
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002477double ExternalDoubleArray::get(int index) {
2478 ASSERT((index >= 0) && (index < this->length()));
2479 double* ptr = static_cast<double*>(external_pointer());
2480 return ptr[index];
2481}
2482
2483
2484void ExternalDoubleArray::set(int index, double value) {
2485 ASSERT((index >= 0) && (index < this->length()));
2486 double* ptr = static_cast<double*>(external_pointer());
2487 ptr[index] = value;
2488}
2489
2490
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002491int Map::visitor_id() {
2492 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2493}
2494
2495
2496void Map::set_visitor_id(int id) {
2497 ASSERT(0 <= id && id < 256);
2498 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2499}
2500
ager@chromium.org3811b432009-10-28 14:53:37 +00002501
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002502int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002503 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2504}
2505
2506
2507int Map::inobject_properties() {
2508 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002509}
2510
2511
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002512int Map::pre_allocated_property_fields() {
2513 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2514}
2515
2516
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002517int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002518 int instance_size = map->instance_size();
2519 if (instance_size != kVariableSizeSentinel) return instance_size;
2520 // We can ignore the "symbol" bit becase it is only set for symbols
2521 // and implies a string type.
2522 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002523 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002524 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002525 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002526 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002527 if (instance_type == ASCII_STRING_TYPE) {
2528 return SeqAsciiString::SizeFor(
2529 reinterpret_cast<SeqAsciiString*>(this)->length());
2530 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002531 if (instance_type == BYTE_ARRAY_TYPE) {
2532 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2533 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002534 if (instance_type == STRING_TYPE) {
2535 return SeqTwoByteString::SizeFor(
2536 reinterpret_cast<SeqTwoByteString*>(this)->length());
2537 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002538 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2539 return FixedDoubleArray::SizeFor(
2540 reinterpret_cast<FixedDoubleArray*>(this)->length());
2541 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002542 ASSERT(instance_type == CODE_TYPE);
2543 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002544}
2545
2546
2547void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002548 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002549 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002550 ASSERT(0 <= value && value < 256);
2551 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2552}
2553
2554
ager@chromium.org7c537e22008-10-16 08:43:32 +00002555void Map::set_inobject_properties(int value) {
2556 ASSERT(0 <= value && value < 256);
2557 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2558}
2559
2560
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002561void Map::set_pre_allocated_property_fields(int value) {
2562 ASSERT(0 <= value && value < 256);
2563 WRITE_BYTE_FIELD(this,
2564 kPreAllocatedPropertyFieldsOffset,
2565 static_cast<byte>(value));
2566}
2567
2568
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002569InstanceType Map::instance_type() {
2570 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2571}
2572
2573
2574void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002575 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2576}
2577
2578
2579int Map::unused_property_fields() {
2580 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2581}
2582
2583
2584void Map::set_unused_property_fields(int value) {
2585 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2586}
2587
2588
2589byte Map::bit_field() {
2590 return READ_BYTE_FIELD(this, kBitFieldOffset);
2591}
2592
2593
2594void Map::set_bit_field(byte value) {
2595 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2596}
2597
2598
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002599byte Map::bit_field2() {
2600 return READ_BYTE_FIELD(this, kBitField2Offset);
2601}
2602
2603
2604void Map::set_bit_field2(byte value) {
2605 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2606}
2607
2608
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002609void Map::set_non_instance_prototype(bool value) {
2610 if (value) {
2611 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2612 } else {
2613 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2614 }
2615}
2616
2617
2618bool Map::has_non_instance_prototype() {
2619 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2620}
2621
2622
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002623void Map::set_function_with_prototype(bool value) {
2624 if (value) {
2625 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2626 } else {
2627 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2628 }
2629}
2630
2631
2632bool Map::function_with_prototype() {
2633 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2634}
2635
2636
ager@chromium.org870a0b62008-11-04 11:43:05 +00002637void Map::set_is_access_check_needed(bool access_check_needed) {
2638 if (access_check_needed) {
2639 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2640 } else {
2641 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2642 }
2643}
2644
2645
2646bool Map::is_access_check_needed() {
2647 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2648}
2649
2650
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002651void Map::set_is_extensible(bool value) {
2652 if (value) {
2653 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2654 } else {
2655 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2656 }
2657}
2658
2659bool Map::is_extensible() {
2660 return ((1 << kIsExtensible) & bit_field2()) != 0;
2661}
2662
2663
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002664void Map::set_attached_to_shared_function_info(bool value) {
2665 if (value) {
2666 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2667 } else {
2668 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2669 }
2670}
2671
2672bool Map::attached_to_shared_function_info() {
2673 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2674}
2675
2676
2677void Map::set_is_shared(bool value) {
2678 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002679 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002680 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002681 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002682 }
2683}
2684
2685bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002686 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002687}
2688
2689
2690JSFunction* Map::unchecked_constructor() {
2691 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2692}
2693
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002694
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002695FixedArray* Map::unchecked_prototype_transitions() {
2696 return reinterpret_cast<FixedArray*>(
2697 READ_FIELD(this, kPrototypeTransitionsOffset));
2698}
2699
2700
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002701Code::Flags Code::flags() {
2702 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2703}
2704
2705
2706void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002707 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002708 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002709 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2710 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002711 ExtractArgumentsCountFromFlags(flags) >= 0);
2712 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2713}
2714
2715
2716Code::Kind Code::kind() {
2717 return ExtractKindFromFlags(flags());
2718}
2719
2720
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002721InLoopFlag Code::ic_in_loop() {
2722 return ExtractICInLoopFromFlags(flags());
2723}
2724
2725
kasper.lund7276f142008-07-30 08:49:36 +00002726InlineCacheState Code::ic_state() {
2727 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002728 // Only allow uninitialized or debugger states for non-IC code
2729 // objects. This is used in the debugger to determine whether or not
2730 // a call to code object has been replaced with a debug break call.
2731 ASSERT(is_inline_cache_stub() ||
2732 result == UNINITIALIZED ||
2733 result == DEBUG_BREAK ||
2734 result == DEBUG_PREPARE_STEP_IN);
2735 return result;
2736}
2737
2738
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002739Code::ExtraICState Code::extra_ic_state() {
2740 ASSERT(is_inline_cache_stub());
2741 return ExtractExtraICStateFromFlags(flags());
2742}
2743
2744
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002745PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002746 return ExtractTypeFromFlags(flags());
2747}
2748
2749
2750int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002751 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002752 return ExtractArgumentsCountFromFlags(flags());
2753}
2754
2755
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002756int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002757 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002758 kind() == UNARY_OP_IC ||
2759 kind() == BINARY_OP_IC ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002760 kind() == COMPARE_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002761 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002762}
2763
2764
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002765void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002766 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002767 kind() == UNARY_OP_IC ||
2768 kind() == BINARY_OP_IC ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002769 kind() == COMPARE_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002770 ASSERT(0 <= major && major < 256);
2771 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002772}
2773
2774
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002775bool Code::optimizable() {
2776 ASSERT(kind() == FUNCTION);
2777 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2778}
2779
2780
2781void Code::set_optimizable(bool value) {
2782 ASSERT(kind() == FUNCTION);
2783 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2784}
2785
2786
2787bool Code::has_deoptimization_support() {
2788 ASSERT(kind() == FUNCTION);
2789 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2790}
2791
2792
2793void Code::set_has_deoptimization_support(bool value) {
2794 ASSERT(kind() == FUNCTION);
2795 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2796}
2797
2798
2799int Code::allow_osr_at_loop_nesting_level() {
2800 ASSERT(kind() == FUNCTION);
2801 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2802}
2803
2804
2805void Code::set_allow_osr_at_loop_nesting_level(int level) {
2806 ASSERT(kind() == FUNCTION);
2807 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2808 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2809}
2810
2811
2812unsigned Code::stack_slots() {
2813 ASSERT(kind() == OPTIMIZED_FUNCTION);
2814 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2815}
2816
2817
2818void Code::set_stack_slots(unsigned slots) {
2819 ASSERT(kind() == OPTIMIZED_FUNCTION);
2820 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2821}
2822
2823
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002824unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002825 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002826 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002827}
2828
2829
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002830void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002831 ASSERT(kind() == OPTIMIZED_FUNCTION);
2832 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002833 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002834}
2835
2836
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002837unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002838 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002839 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002840}
2841
2842
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002843void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002844 ASSERT(kind() == FUNCTION);
2845 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002846 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002847}
2848
2849
2850CheckType Code::check_type() {
2851 ASSERT(is_call_stub() || is_keyed_call_stub());
2852 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2853 return static_cast<CheckType>(type);
2854}
2855
2856
2857void Code::set_check_type(CheckType value) {
2858 ASSERT(is_call_stub() || is_keyed_call_stub());
2859 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2860}
2861
2862
danno@chromium.org40cb8782011-05-25 07:58:50 +00002863byte Code::unary_op_type() {
2864 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002865 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
2866}
2867
2868
danno@chromium.org40cb8782011-05-25 07:58:50 +00002869void Code::set_unary_op_type(byte value) {
2870 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002871 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
2872}
2873
2874
danno@chromium.org40cb8782011-05-25 07:58:50 +00002875byte Code::binary_op_type() {
2876 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002877 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2878}
2879
2880
danno@chromium.org40cb8782011-05-25 07:58:50 +00002881void Code::set_binary_op_type(byte value) {
2882 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002883 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2884}
2885
2886
danno@chromium.org40cb8782011-05-25 07:58:50 +00002887byte Code::binary_op_result_type() {
2888 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002889 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2890}
2891
2892
danno@chromium.org40cb8782011-05-25 07:58:50 +00002893void Code::set_binary_op_result_type(byte value) {
2894 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002895 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2896}
2897
2898
2899byte Code::compare_state() {
2900 ASSERT(is_compare_ic_stub());
2901 return READ_BYTE_FIELD(this, kCompareStateOffset);
2902}
2903
2904
2905void Code::set_compare_state(byte value) {
2906 ASSERT(is_compare_ic_stub());
2907 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2908}
2909
2910
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002911bool Code::is_inline_cache_stub() {
2912 Kind kind = this->kind();
2913 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2914}
2915
2916
2917Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002918 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002919 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002920 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002921 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002922 int argc,
2923 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002924 // Extra IC state is only allowed for call IC stubs or for store IC
2925 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002926 ASSERT(extra_ic_state == kNoExtraICState ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002927 (kind == CALL_IC) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00002928 (kind == STORE_IC) ||
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002929 (kind == KEYED_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002930 // Compute the bit mask.
2931 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002932 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002933 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002934 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002935 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002936 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002937 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002938 // Cast to flags and validate result before returning it.
2939 Flags result = static_cast<Flags>(bits);
2940 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002941 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002942 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002943 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002944 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002945 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2946 return result;
2947}
2948
2949
2950Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2951 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002952 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002953 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002954 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002955 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002956 return ComputeFlags(
2957 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002958}
2959
2960
2961Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2962 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2963 return static_cast<Kind>(bits);
2964}
2965
2966
kasper.lund7276f142008-07-30 08:49:36 +00002967InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2968 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002969 return static_cast<InlineCacheState>(bits);
2970}
2971
2972
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002973Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
2974 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
2975 return static_cast<ExtraICState>(bits);
2976}
2977
2978
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002979InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2980 int bits = (flags & kFlagsICInLoopMask);
2981 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2982}
2983
2984
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002985PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2986 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2987 return static_cast<PropertyType>(bits);
2988}
2989
2990
2991int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2992 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2993}
2994
2995
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002996InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2997 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2998 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2999}
3000
3001
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003002Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
3003 int bits = flags & ~kFlagsTypeMask;
3004 return static_cast<Flags>(bits);
3005}
3006
3007
ager@chromium.org8bb60582008-12-11 12:02:20 +00003008Code* Code::GetCodeFromTargetAddress(Address address) {
3009 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3010 // GetCodeFromTargetAddress might be called when marking objects during mark
3011 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3012 // Code::cast. Code::cast does not work when the object's map is
3013 // marked.
3014 Code* result = reinterpret_cast<Code*>(code);
3015 return result;
3016}
3017
3018
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003019Isolate* Map::isolate() {
3020 return heap()->isolate();
3021}
3022
3023
3024Heap* Map::heap() {
3025 // NOTE: address() helper is not used to save one instruction.
3026 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3027 ASSERT(heap != NULL);
3028 ASSERT(heap->isolate() == Isolate::Current());
3029 return heap;
3030}
3031
3032
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003033Heap* Code::heap() {
3034 // NOTE: address() helper is not used to save one instruction.
3035 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3036 ASSERT(heap != NULL);
3037 ASSERT(heap->isolate() == Isolate::Current());
3038 return heap;
3039}
3040
3041
3042Isolate* Code::isolate() {
3043 return heap()->isolate();
3044}
3045
3046
3047Heap* JSGlobalPropertyCell::heap() {
3048 // NOTE: address() helper is not used to save one instruction.
3049 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3050 ASSERT(heap != NULL);
3051 ASSERT(heap->isolate() == Isolate::Current());
3052 return heap;
3053}
3054
3055
3056Isolate* JSGlobalPropertyCell::isolate() {
3057 return heap()->isolate();
3058}
3059
3060
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003061Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3062 return HeapObject::
3063 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3064}
3065
3066
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003067Object* Map::prototype() {
3068 return READ_FIELD(this, kPrototypeOffset);
3069}
3070
3071
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003072void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003073 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003074 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003075 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003076}
3077
3078
lrn@chromium.org303ada72010-10-27 09:33:13 +00003079MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003080 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003081 Object* obj;
3082 { MaybeObject* maybe_obj = CopyDropTransitions();
3083 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3084 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003085 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003086 new_map->set_elements_kind(JSObject::FAST_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003087 isolate()->counters()->map_to_fast_elements()->Increment();
3088 return new_map;
3089}
3090
3091
3092MaybeObject* Map::GetFastDoubleElementsMap() {
3093 if (has_fast_double_elements()) return this;
3094 Object* obj;
3095 { MaybeObject* maybe_obj = CopyDropTransitions();
3096 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3097 }
3098 Map* new_map = Map::cast(obj);
3099 new_map->set_elements_kind(JSObject::FAST_DOUBLE_ELEMENTS);
3100 isolate()->counters()->map_to_fast_double_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003101 return new_map;
3102}
3103
3104
lrn@chromium.org303ada72010-10-27 09:33:13 +00003105MaybeObject* Map::GetSlowElementsMap() {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003106 if (!has_fast_elements() && !has_fast_double_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003107 Object* obj;
3108 { MaybeObject* maybe_obj = CopyDropTransitions();
3109 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3110 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003111 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003112 new_map->set_elements_kind(JSObject::DICTIONARY_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003113 isolate()->counters()->map_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003114 return new_map;
3115}
3116
3117
danno@chromium.org40cb8782011-05-25 07:58:50 +00003118DescriptorArray* Map::instance_descriptors() {
3119 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3120 if (object->IsSmi()) {
3121 return HEAP->empty_descriptor_array();
3122 } else {
3123 return DescriptorArray::cast(object);
3124 }
3125}
3126
3127
3128void Map::init_instance_descriptors() {
3129 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3130}
3131
3132
3133void Map::clear_instance_descriptors() {
3134 Object* object = READ_FIELD(this,
3135 kInstanceDescriptorsOrBitField3Offset);
3136 if (!object->IsSmi()) {
3137 WRITE_FIELD(
3138 this,
3139 kInstanceDescriptorsOrBitField3Offset,
3140 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3141 }
3142}
3143
3144
3145void Map::set_instance_descriptors(DescriptorArray* value,
3146 WriteBarrierMode mode) {
3147 Object* object = READ_FIELD(this,
3148 kInstanceDescriptorsOrBitField3Offset);
3149 if (value == isolate()->heap()->empty_descriptor_array()) {
3150 clear_instance_descriptors();
3151 return;
3152 } else {
3153 if (object->IsSmi()) {
3154 value->set_bit_field3_storage(Smi::cast(object)->value());
3155 } else {
3156 value->set_bit_field3_storage(
3157 DescriptorArray::cast(object)->bit_field3_storage());
3158 }
3159 }
3160 ASSERT(!is_shared());
3161 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
3162 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3163 this,
3164 kInstanceDescriptorsOrBitField3Offset,
3165 mode);
3166}
3167
3168
3169int Map::bit_field3() {
3170 Object* object = READ_FIELD(this,
3171 kInstanceDescriptorsOrBitField3Offset);
3172 if (object->IsSmi()) {
3173 return Smi::cast(object)->value();
3174 } else {
3175 return DescriptorArray::cast(object)->bit_field3_storage();
3176 }
3177}
3178
3179
3180void Map::set_bit_field3(int value) {
3181 ASSERT(Smi::IsValid(value));
3182 Object* object = READ_FIELD(this,
3183 kInstanceDescriptorsOrBitField3Offset);
3184 if (object->IsSmi()) {
3185 WRITE_FIELD(this,
3186 kInstanceDescriptorsOrBitField3Offset,
3187 Smi::FromInt(value));
3188 } else {
3189 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3190 }
3191}
3192
3193
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003194ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003195ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003196ACCESSORS(Map, constructor, Object, kConstructorOffset)
3197
3198ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
3199ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003200ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
3201 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003202
3203ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3204ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003205ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003206
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003207ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003208
3209ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3210ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3211ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3212ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3213ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3214
3215ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3216ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3217ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3218
3219ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3220ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3221ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3222ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3223ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3224ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3225
3226ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3227ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3228
3229ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3230ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3231
3232ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3233ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003234ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3235 kPropertyAccessorsOffset)
3236ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3237 kPrototypeTemplateOffset)
3238ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3239ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3240 kNamedPropertyHandlerOffset)
3241ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3242 kIndexedPropertyHandlerOffset)
3243ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3244 kInstanceTemplateOffset)
3245ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3246ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003247ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3248 kInstanceCallHandlerOffset)
3249ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3250 kAccessCheckInfoOffset)
3251ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
ager@chromium.org04921a82011-06-27 13:21:41 +00003252ACCESSORS(FunctionTemplateInfo, prototype_attributes, Smi,
3253 kPrototypeAttributesOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003254
3255ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003256ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3257 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003258
3259ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3260ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3261
3262ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3263
3264ACCESSORS(Script, source, Object, kSourceOffset)
3265ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003266ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003267ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3268ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003269ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003270ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003271ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003272ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003273ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003274ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003275ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003276ACCESSORS(Script, eval_from_instructions_offset, Smi,
3277 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003278
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003279#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003280ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3281ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3282ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3283ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3284
3285ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3286ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3287ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3288ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003289#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003290
3291ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003292ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3293ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003294ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3295 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003296ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003297ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3298ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003299ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003300ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3301 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003302
3303BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3304 kHiddenPrototypeBit)
3305BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3306BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3307 kNeedsAccessCheckBit)
3308BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3309 kIsExpressionBit)
3310BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3311 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003312BOOL_GETTER(SharedFunctionInfo,
3313 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003314 has_only_simple_this_property_assignments,
3315 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003316BOOL_ACCESSORS(SharedFunctionInfo,
3317 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003318 allows_lazy_compilation,
3319 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003320BOOL_ACCESSORS(SharedFunctionInfo,
3321 compiler_hints,
3322 uses_arguments,
3323 kUsesArguments)
3324BOOL_ACCESSORS(SharedFunctionInfo,
3325 compiler_hints,
3326 has_duplicate_parameters,
3327 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003328
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003329
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003330#if V8_HOST_ARCH_32_BIT
3331SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3332SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003333 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003334SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003335 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003336SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3337SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003338 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003339SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3340SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003341 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003342SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003343 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003344SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003345 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003346SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003347#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003348
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003349#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003350 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003351 int holder::name() { \
3352 int value = READ_INT_FIELD(this, offset); \
3353 ASSERT(kHeapObjectTag == 1); \
3354 ASSERT((value & kHeapObjectTag) == 0); \
3355 return value >> 1; \
3356 } \
3357 void holder::set_##name(int value) { \
3358 ASSERT(kHeapObjectTag == 1); \
3359 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3360 (value & 0xC0000000) == 0x000000000); \
3361 WRITE_INT_FIELD(this, \
3362 offset, \
3363 (value << 1) & ~kHeapObjectTag); \
3364 }
3365
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003366#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3367 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003368 INT_ACCESSORS(holder, name, offset)
3369
3370
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003371PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003372PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3373 formal_parameter_count,
3374 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003375
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003376PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3377 expected_nof_properties,
3378 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003379PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3380
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003381PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3382PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3383 start_position_and_type,
3384 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003385
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003386PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3387 function_token_position,
3388 kFunctionTokenPositionOffset)
3389PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3390 compiler_hints,
3391 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003392
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003393PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3394 this_property_assignments_count,
3395 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003396PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003397#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003398
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003399
3400int SharedFunctionInfo::construction_count() {
3401 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3402}
3403
3404
3405void SharedFunctionInfo::set_construction_count(int value) {
3406 ASSERT(0 <= value && value < 256);
3407 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3408}
3409
3410
whesse@chromium.org7b260152011-06-20 15:33:18 +00003411BOOL_ACCESSORS(SharedFunctionInfo,
3412 compiler_hints,
3413 live_objects_may_exist,
3414 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003415
3416
3417bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003418 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003419}
3420
3421
whesse@chromium.org7b260152011-06-20 15:33:18 +00003422BOOL_GETTER(SharedFunctionInfo,
3423 compiler_hints,
3424 optimization_disabled,
3425 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003426
3427
3428void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3429 set_compiler_hints(BooleanBit::set(compiler_hints(),
3430 kOptimizationDisabled,
3431 disable));
3432 // If disabling optimizations we reflect that in the code object so
3433 // it will not be counted as optimizable code.
3434 if ((code()->kind() == Code::FUNCTION) && disable) {
3435 code()->set_optimizable(false);
3436 }
3437}
3438
3439
whesse@chromium.org7b260152011-06-20 15:33:18 +00003440BOOL_ACCESSORS(SharedFunctionInfo,
3441 compiler_hints,
3442 strict_mode,
3443 kStrictModeFunction)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003444
3445
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003446bool SharedFunctionInfo::native() {
3447 return BooleanBit::get(compiler_hints(), kNative);
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003448}
3449
3450
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003451void SharedFunctionInfo::set_native(bool value) {
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003452 set_compiler_hints(BooleanBit::set(compiler_hints(),
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003453 kNative,
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003454 value));
3455}
3456
3457
whesse@chromium.org7b260152011-06-20 15:33:18 +00003458bool SharedFunctionInfo::bound() {
3459 return BooleanBit::get(compiler_hints(), kBoundFunction);
3460}
3461
3462
3463void SharedFunctionInfo::set_bound(bool value) {
3464 set_compiler_hints(BooleanBit::set(compiler_hints(),
3465 kBoundFunction,
3466 value));
3467}
3468
3469
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003470ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3471ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3472
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003473ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3474
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003475bool Script::HasValidSource() {
3476 Object* src = this->source();
3477 if (!src->IsString()) return true;
3478 String* src_str = String::cast(src);
3479 if (!StringShape(src_str).IsExternal()) return true;
3480 if (src_str->IsAsciiRepresentation()) {
3481 return ExternalAsciiString::cast(src)->resource() != NULL;
3482 } else if (src_str->IsTwoByteRepresentation()) {
3483 return ExternalTwoByteString::cast(src)->resource() != NULL;
3484 }
3485 return true;
3486}
3487
3488
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003489void SharedFunctionInfo::DontAdaptArguments() {
3490 ASSERT(code()->kind() == Code::BUILTIN);
3491 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3492}
3493
3494
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003495int SharedFunctionInfo::start_position() {
3496 return start_position_and_type() >> kStartPositionShift;
3497}
3498
3499
3500void SharedFunctionInfo::set_start_position(int start_position) {
3501 set_start_position_and_type((start_position << kStartPositionShift)
3502 | (start_position_and_type() & ~kStartPositionMask));
3503}
3504
3505
3506Code* SharedFunctionInfo::code() {
3507 return Code::cast(READ_FIELD(this, kCodeOffset));
3508}
3509
3510
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003511Code* SharedFunctionInfo::unchecked_code() {
3512 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3513}
3514
3515
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003516void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003517 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003518 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003519}
3520
3521
ager@chromium.orgb5737492010-07-15 09:29:43 +00003522SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3523 return reinterpret_cast<SerializedScopeInfo*>(
3524 READ_FIELD(this, kScopeInfoOffset));
3525}
3526
3527
3528void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3529 WriteBarrierMode mode) {
3530 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003531 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003532}
3533
3534
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003535Smi* SharedFunctionInfo::deopt_counter() {
3536 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3537}
3538
3539
3540void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3541 WRITE_FIELD(this, kDeoptCounterOffset, value);
3542}
3543
3544
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003545bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003546 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003547 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003548}
3549
3550
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003551bool SharedFunctionInfo::IsApiFunction() {
3552 return function_data()->IsFunctionTemplateInfo();
3553}
3554
3555
3556FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3557 ASSERT(IsApiFunction());
3558 return FunctionTemplateInfo::cast(function_data());
3559}
3560
3561
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003562bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003563 return function_data()->IsSmi();
3564}
3565
3566
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003567BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3568 ASSERT(HasBuiltinFunctionId());
3569 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003570}
3571
3572
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003573int SharedFunctionInfo::code_age() {
3574 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3575}
3576
3577
3578void SharedFunctionInfo::set_code_age(int code_age) {
3579 set_compiler_hints(compiler_hints() |
3580 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3581}
3582
3583
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003584bool SharedFunctionInfo::has_deoptimization_support() {
3585 Code* code = this->code();
3586 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3587}
3588
3589
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003590bool JSFunction::IsBuiltin() {
3591 return context()->global()->IsJSBuiltinsObject();
3592}
3593
3594
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003595bool JSFunction::NeedsArgumentsAdaption() {
3596 return shared()->formal_parameter_count() !=
3597 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3598}
3599
3600
3601bool JSFunction::IsOptimized() {
3602 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3603}
3604
3605
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003606bool JSFunction::IsOptimizable() {
3607 return code()->kind() == Code::FUNCTION && code()->optimizable();
3608}
3609
3610
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003611bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003612 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003613}
3614
3615
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003616Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003617 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003618}
3619
3620
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003621Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003622 return reinterpret_cast<Code*>(
3623 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003624}
3625
3626
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003627void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003628 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003629 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003630 Address entry = value->entry();
3631 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003632}
3633
3634
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003635void JSFunction::ReplaceCode(Code* code) {
3636 bool was_optimized = IsOptimized();
3637 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3638
3639 set_code(code);
3640
3641 // Add/remove the function from the list of optimized functions for this
3642 // context based on the state change.
3643 if (!was_optimized && is_optimized) {
3644 context()->global_context()->AddOptimizedFunction(this);
3645 }
3646 if (was_optimized && !is_optimized) {
3647 context()->global_context()->RemoveOptimizedFunction(this);
3648 }
3649}
3650
3651
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003652Context* JSFunction::context() {
3653 return Context::cast(READ_FIELD(this, kContextOffset));
3654}
3655
3656
3657Object* JSFunction::unchecked_context() {
3658 return READ_FIELD(this, kContextOffset);
3659}
3660
3661
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003662SharedFunctionInfo* JSFunction::unchecked_shared() {
3663 return reinterpret_cast<SharedFunctionInfo*>(
3664 READ_FIELD(this, kSharedFunctionInfoOffset));
3665}
3666
3667
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003668void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003669 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003670 WRITE_FIELD(this, kContextOffset, value);
3671 WRITE_BARRIER(this, kContextOffset);
3672}
3673
3674ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3675 kPrototypeOrInitialMapOffset)
3676
3677
3678Map* JSFunction::initial_map() {
3679 return Map::cast(prototype_or_initial_map());
3680}
3681
3682
3683void JSFunction::set_initial_map(Map* value) {
3684 set_prototype_or_initial_map(value);
3685}
3686
3687
3688bool JSFunction::has_initial_map() {
3689 return prototype_or_initial_map()->IsMap();
3690}
3691
3692
3693bool JSFunction::has_instance_prototype() {
3694 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3695}
3696
3697
3698bool JSFunction::has_prototype() {
3699 return map()->has_non_instance_prototype() || has_instance_prototype();
3700}
3701
3702
3703Object* JSFunction::instance_prototype() {
3704 ASSERT(has_instance_prototype());
3705 if (has_initial_map()) return initial_map()->prototype();
3706 // When there is no initial map and the prototype is a JSObject, the
3707 // initial map field is used for the prototype field.
3708 return prototype_or_initial_map();
3709}
3710
3711
3712Object* JSFunction::prototype() {
3713 ASSERT(has_prototype());
3714 // If the function's prototype property has been set to a non-JSObject
3715 // value, that value is stored in the constructor field of the map.
3716 if (map()->has_non_instance_prototype()) return map()->constructor();
3717 return instance_prototype();
3718}
3719
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003720bool JSFunction::should_have_prototype() {
3721 return map()->function_with_prototype();
3722}
3723
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003724
3725bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003726 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003727}
3728
3729
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003730int JSFunction::NumberOfLiterals() {
3731 return literals()->length();
3732}
3733
3734
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003735Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003736 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003737 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003738}
3739
3740
3741void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3742 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003743 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003744 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3745 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3746}
3747
3748
3749Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003750 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003751 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3752}
3753
3754
3755void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3756 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003757 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003758 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003759 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003760}
3761
3762
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003763ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
3764
3765
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003766Address Foreign::address() {
3767 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003768}
3769
3770
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003771void Foreign::set_address(Address value) {
3772 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003773}
3774
3775
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003776ACCESSORS(JSValue, value, Object, kValueOffset)
3777
3778
3779JSValue* JSValue::cast(Object* obj) {
3780 ASSERT(obj->IsJSValue());
3781 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3782 return reinterpret_cast<JSValue*>(obj);
3783}
3784
3785
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003786ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3787ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3788ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3789ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3790ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3791SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3792SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3793
3794
3795JSMessageObject* JSMessageObject::cast(Object* obj) {
3796 ASSERT(obj->IsJSMessageObject());
3797 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3798 return reinterpret_cast<JSMessageObject*>(obj);
3799}
3800
3801
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003802INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003803ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003804ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003805ACCESSORS(Code, next_code_flushing_candidate,
3806 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003807
3808
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003809byte* Code::instruction_start() {
3810 return FIELD_ADDR(this, kHeaderSize);
3811}
3812
3813
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003814byte* Code::instruction_end() {
3815 return instruction_start() + instruction_size();
3816}
3817
3818
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003819int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003820 return RoundUp(instruction_size(), kObjectAlignment);
3821}
3822
3823
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003824FixedArray* Code::unchecked_deoptimization_data() {
3825 return reinterpret_cast<FixedArray*>(
3826 READ_FIELD(this, kDeoptimizationDataOffset));
3827}
3828
3829
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003830ByteArray* Code::unchecked_relocation_info() {
3831 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003832}
3833
3834
3835byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003836 return unchecked_relocation_info()->GetDataStartAddress();
3837}
3838
3839
3840int Code::relocation_size() {
3841 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003842}
3843
3844
3845byte* Code::entry() {
3846 return instruction_start();
3847}
3848
3849
3850bool Code::contains(byte* pc) {
3851 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003852 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003853}
3854
3855
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003856ACCESSORS(JSArray, length, Object, kLengthOffset)
3857
3858
ager@chromium.org236ad962008-09-25 09:45:57 +00003859ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003860
3861
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003862JSRegExp::Type JSRegExp::TypeTag() {
3863 Object* data = this->data();
3864 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3865 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3866 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003867}
3868
3869
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003870JSRegExp::Type JSRegExp::TypeTagUnchecked() {
3871 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
3872 return static_cast<JSRegExp::Type>(smi->value());
3873}
3874
3875
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003876int JSRegExp::CaptureCount() {
3877 switch (TypeTag()) {
3878 case ATOM:
3879 return 0;
3880 case IRREGEXP:
3881 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3882 default:
3883 UNREACHABLE();
3884 return -1;
3885 }
3886}
3887
3888
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003889JSRegExp::Flags JSRegExp::GetFlags() {
3890 ASSERT(this->data()->IsFixedArray());
3891 Object* data = this->data();
3892 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3893 return Flags(smi->value());
3894}
3895
3896
3897String* JSRegExp::Pattern() {
3898 ASSERT(this->data()->IsFixedArray());
3899 Object* data = this->data();
3900 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3901 return pattern;
3902}
3903
3904
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003905Object* JSRegExp::DataAt(int index) {
3906 ASSERT(TypeTag() != NOT_COMPILED);
3907 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003908}
3909
3910
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003911Object* JSRegExp::DataAtUnchecked(int index) {
3912 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
3913 int offset = FixedArray::kHeaderSize + index * kPointerSize;
3914 return READ_FIELD(fa, offset);
3915}
3916
3917
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003918void JSRegExp::SetDataAt(int index, Object* value) {
3919 ASSERT(TypeTag() != NOT_COMPILED);
3920 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3921 FixedArray::cast(data())->set(index, value);
3922}
3923
3924
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003925void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
3926 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3927 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
3928 if (value->IsSmi()) {
3929 fa->set_unchecked(index, Smi::cast(value));
3930 } else {
3931 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
3932 }
3933}
3934
3935
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003936JSObject::ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003937 ElementsKind kind = map()->elements_kind();
3938 ASSERT((kind == FAST_ELEMENTS &&
3939 (elements()->map() == GetHeap()->fixed_array_map() ||
3940 elements()->map() == GetHeap()->fixed_cow_array_map())) ||
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003941 (kind == FAST_DOUBLE_ELEMENTS &&
3942 elements()->IsFixedDoubleArray()) ||
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003943 (kind == DICTIONARY_ELEMENTS &&
3944 elements()->IsFixedArray() &&
3945 elements()->IsDictionary()) ||
3946 (kind > DICTIONARY_ELEMENTS));
3947 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003948}
3949
3950
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003951bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003952 return GetElementsKind() == FAST_ELEMENTS;
3953}
3954
3955
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003956bool JSObject::HasFastDoubleElements() {
3957 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
3958}
3959
3960
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003961bool JSObject::HasDictionaryElements() {
3962 return GetElementsKind() == DICTIONARY_ELEMENTS;
3963}
3964
3965
ager@chromium.org3811b432009-10-28 14:53:37 +00003966bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003967 HeapObject* array = elements();
3968 ASSERT(array != NULL);
3969 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00003970}
3971
3972
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003973#define EXTERNAL_ELEMENTS_CHECK(name, type) \
3974bool JSObject::HasExternal##name##Elements() { \
3975 HeapObject* array = elements(); \
3976 ASSERT(array != NULL); \
3977 if (!array->IsHeapObject()) \
3978 return false; \
3979 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00003980}
3981
3982
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003983EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
3984EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
3985EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
3986EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
3987 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
3988EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
3989EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
3990 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
3991EXTERNAL_ELEMENTS_CHECK(Float,
3992 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003993EXTERNAL_ELEMENTS_CHECK(Double,
3994 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003995EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00003996
3997
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003998bool JSObject::HasNamedInterceptor() {
3999 return map()->has_named_interceptor();
4000}
4001
4002
4003bool JSObject::HasIndexedInterceptor() {
4004 return map()->has_indexed_interceptor();
4005}
4006
4007
ager@chromium.org5c838252010-02-19 08:53:10 +00004008bool JSObject::AllowsSetElementsLength() {
4009 bool result = elements()->IsFixedArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004010 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00004011 return result;
4012}
4013
4014
lrn@chromium.org303ada72010-10-27 09:33:13 +00004015MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004016 ASSERT(HasFastElements());
4017 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004018 Isolate* isolate = GetIsolate();
4019 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004020 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004021 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4022 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004023 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4024 return maybe_writable_elems;
4025 }
4026 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004027 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004028 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004029 return writable_elems;
4030}
4031
4032
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004033StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004034 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004035 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004036}
4037
4038
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004039NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004040 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004041 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004042}
4043
4044
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004045bool String::IsHashFieldComputed(uint32_t field) {
4046 return (field & kHashNotComputedMask) == 0;
4047}
4048
4049
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004050bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004051 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004052}
4053
4054
4055uint32_t String::Hash() {
4056 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004057 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004058 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004059 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004060 return ComputeAndSetHash();
4061}
4062
4063
ager@chromium.org7c537e22008-10-16 08:43:32 +00004064StringHasher::StringHasher(int length)
4065 : length_(length),
4066 raw_running_hash_(0),
4067 array_index_(0),
4068 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4069 is_first_char_(true),
4070 is_valid_(true) { }
4071
4072
4073bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004074 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004075}
4076
4077
4078void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004079 // Use the Jenkins one-at-a-time hash function to update the hash
4080 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004081 raw_running_hash_ += c;
4082 raw_running_hash_ += (raw_running_hash_ << 10);
4083 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004084 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004085 if (is_array_index_) {
4086 if (c < '0' || c > '9') {
4087 is_array_index_ = false;
4088 } else {
4089 int d = c - '0';
4090 if (is_first_char_) {
4091 is_first_char_ = false;
4092 if (c == '0' && length_ > 1) {
4093 is_array_index_ = false;
4094 return;
4095 }
4096 }
4097 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4098 is_array_index_ = false;
4099 } else {
4100 array_index_ = array_index_ * 10 + d;
4101 }
4102 }
4103 }
4104}
4105
4106
4107void StringHasher::AddCharacterNoIndex(uc32 c) {
4108 ASSERT(!is_array_index());
4109 raw_running_hash_ += c;
4110 raw_running_hash_ += (raw_running_hash_ << 10);
4111 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4112}
4113
4114
4115uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004116 // Get the calculated raw hash value and do some more bit ops to distribute
4117 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004118 uint32_t result = raw_running_hash_;
4119 result += (result << 3);
4120 result ^= (result >> 11);
4121 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004122 if (result == 0) {
4123 result = 27;
4124 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004125 return result;
4126}
4127
4128
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004129template <typename schar>
4130uint32_t HashSequentialString(const schar* chars, int length) {
4131 StringHasher hasher(length);
4132 if (!hasher.has_trivial_hash()) {
4133 int i;
4134 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4135 hasher.AddCharacter(chars[i]);
4136 }
4137 for (; i < length; i++) {
4138 hasher.AddCharacterNoIndex(chars[i]);
4139 }
4140 }
4141 return hasher.GetHashField();
4142}
4143
4144
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004145bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004146 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004147 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4148 return false;
4149 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004150 return SlowAsArrayIndex(index);
4151}
4152
4153
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004154Object* JSReceiver::GetPrototype() {
4155 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004156}
4157
4158
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004159PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004160 return GetPropertyAttributeWithReceiver(this, key);
4161}
4162
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004163// TODO(504): this may be useful in other places too where JSGlobalProxy
4164// is used.
4165Object* JSObject::BypassGlobalProxy() {
4166 if (IsJSGlobalProxy()) {
4167 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004168 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004169 ASSERT(proto->IsJSGlobalObject());
4170 return proto;
4171 }
4172 return this;
4173}
4174
4175
4176bool JSObject::HasHiddenPropertiesObject() {
4177 ASSERT(!IsJSGlobalProxy());
4178 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004179 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004180 false) != ABSENT;
4181}
4182
4183
4184Object* JSObject::GetHiddenPropertiesObject() {
4185 ASSERT(!IsJSGlobalProxy());
4186 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004187 // You can't install a getter on a property indexed by the hidden symbol,
4188 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
4189 // object.
4190 Object* result =
4191 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004192 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00004193 &attributes)->ToObjectUnchecked();
4194 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004195}
4196
4197
lrn@chromium.org303ada72010-10-27 09:33:13 +00004198MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004199 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004200 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004201 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00004202 DONT_ENUM,
4203 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004204}
4205
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004206
4207bool JSObject::HasElement(uint32_t index) {
4208 return HasElementWithReceiver(this, index);
4209}
4210
4211
4212bool AccessorInfo::all_can_read() {
4213 return BooleanBit::get(flag(), kAllCanReadBit);
4214}
4215
4216
4217void AccessorInfo::set_all_can_read(bool value) {
4218 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4219}
4220
4221
4222bool AccessorInfo::all_can_write() {
4223 return BooleanBit::get(flag(), kAllCanWriteBit);
4224}
4225
4226
4227void AccessorInfo::set_all_can_write(bool value) {
4228 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4229}
4230
4231
ager@chromium.org870a0b62008-11-04 11:43:05 +00004232bool AccessorInfo::prohibits_overwriting() {
4233 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4234}
4235
4236
4237void AccessorInfo::set_prohibits_overwriting(bool value) {
4238 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4239}
4240
4241
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004242PropertyAttributes AccessorInfo::property_attributes() {
4243 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4244}
4245
4246
4247void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
4248 ASSERT(AttributesField::is_valid(attributes));
4249 int rest_value = flag()->value() & ~AttributesField::mask();
4250 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
4251}
4252
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004253
4254template<typename Shape, typename Key>
4255void Dictionary<Shape, Key>::SetEntry(int entry,
4256 Object* key,
4257 Object* value) {
4258 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4259}
4260
4261
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004262template<typename Shape, typename Key>
4263void Dictionary<Shape, Key>::SetEntry(int entry,
4264 Object* key,
4265 Object* value,
4266 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004267 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004268 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004269 AssertNoAllocation no_gc;
4270 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004271 FixedArray::set(index, key, mode);
4272 FixedArray::set(index+1, value, mode);
4273 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004274}
4275
4276
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004277bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4278 ASSERT(other->IsNumber());
4279 return key == static_cast<uint32_t>(other->Number());
4280}
4281
4282
4283uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4284 return ComputeIntegerHash(key);
4285}
4286
4287
4288uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4289 ASSERT(other->IsNumber());
4290 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4291}
4292
4293
4294MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4295 return Isolate::Current()->heap()->NumberFromUint32(key);
4296}
4297
4298
4299bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4300 // We know that all entries in a hash table had their hash keys created.
4301 // Use that knowledge to have fast failure.
4302 if (key->Hash() != String::cast(other)->Hash()) return false;
4303 return key->Equals(String::cast(other));
4304}
4305
4306
4307uint32_t StringDictionaryShape::Hash(String* key) {
4308 return key->Hash();
4309}
4310
4311
4312uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4313 return String::cast(other)->Hash();
4314}
4315
4316
4317MaybeObject* StringDictionaryShape::AsObject(String* key) {
4318 return key;
4319}
4320
4321
4322void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004323 // No write barrier is needed since empty_fixed_array is not in new space.
4324 // Please note this function is used during marking:
4325 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004326 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4327 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004328}
4329
4330
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004331void JSArray::EnsureSize(int required_size) {
4332 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004333 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004334 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4335 if (elts->length() < required_size) {
4336 // Doubling in size would be overkill, but leave some slack to avoid
4337 // constantly growing.
4338 Expand(required_size + (required_size >> 3));
4339 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004340 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004341 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4342 // Expand will allocate a new backing store in new space even if the size
4343 // we asked for isn't larger than what we had before.
4344 Expand(required_size);
4345 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004346}
4347
4348
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004349void JSArray::set_length(Smi* length) {
4350 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4351}
4352
4353
ager@chromium.org7c537e22008-10-16 08:43:32 +00004354void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004355 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004356 set_elements(storage);
4357}
4358
4359
lrn@chromium.org303ada72010-10-27 09:33:13 +00004360MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004361 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004362 return GetHeap()->CopyFixedArray(this);
4363}
4364
4365
4366Relocatable::Relocatable(Isolate* isolate) {
4367 ASSERT(isolate == Isolate::Current());
4368 isolate_ = isolate;
4369 prev_ = isolate->relocatable_top();
4370 isolate->set_relocatable_top(this);
4371}
4372
4373
4374Relocatable::~Relocatable() {
4375 ASSERT(isolate_ == Isolate::Current());
4376 ASSERT_EQ(isolate_->relocatable_top(), this);
4377 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004378}
4379
4380
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004381int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4382 return map->instance_size();
4383}
4384
4385
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004386void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004387 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004388 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004389}
4390
4391
4392template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004393void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004394 StaticVisitor::VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004395 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004396}
4397
4398
4399void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4400 typedef v8::String::ExternalAsciiStringResource Resource;
4401 v->VisitExternalAsciiString(
4402 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4403}
4404
4405
4406template<typename StaticVisitor>
4407void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4408 typedef v8::String::ExternalAsciiStringResource Resource;
4409 StaticVisitor::VisitExternalAsciiString(
4410 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4411}
4412
4413
4414void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4415 typedef v8::String::ExternalStringResource Resource;
4416 v->VisitExternalTwoByteString(
4417 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4418}
4419
4420
4421template<typename StaticVisitor>
4422void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4423 typedef v8::String::ExternalStringResource Resource;
4424 StaticVisitor::VisitExternalTwoByteString(
4425 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4426}
4427
4428#define SLOT_ADDR(obj, offset) \
4429 reinterpret_cast<Object**>((obj)->address() + offset)
4430
4431template<int start_offset, int end_offset, int size>
4432void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4433 HeapObject* obj,
4434 ObjectVisitor* v) {
4435 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4436}
4437
4438
4439template<int start_offset>
4440void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4441 int object_size,
4442 ObjectVisitor* v) {
4443 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4444}
4445
4446#undef SLOT_ADDR
4447
4448
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004449#undef CAST_ACCESSOR
4450#undef INT_ACCESSORS
4451#undef SMI_ACCESSORS
4452#undef ACCESSORS
4453#undef FIELD_ADDR
4454#undef READ_FIELD
4455#undef WRITE_FIELD
4456#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004457#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004458#undef READ_MEMADDR_FIELD
4459#undef WRITE_MEMADDR_FIELD
4460#undef READ_DOUBLE_FIELD
4461#undef WRITE_DOUBLE_FIELD
4462#undef READ_INT_FIELD
4463#undef WRITE_INT_FIELD
4464#undef READ_SHORT_FIELD
4465#undef WRITE_SHORT_FIELD
4466#undef READ_BYTE_FIELD
4467#undef WRITE_BYTE_FIELD
4468
4469
4470} } // namespace v8::internal
4471
4472#endif // V8_OBJECTS_INL_H_