blob: 34b7c2e229c457c7212514c3f1856094000c966d [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
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000161bool Object::IsSpecObject() {
162 return Object::IsHeapObject()
163 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
164}
165
166
ager@chromium.org870a0b62008-11-04 11:43:05 +0000167bool Object::IsSymbol() {
168 if (!this->IsHeapObject()) return false;
169 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000170 // Because the symbol tag is non-zero and no non-string types have the
171 // symbol bit set we can test for symbols with a very simple test
172 // operation.
173 ASSERT(kSymbolTag != 0);
174 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
175 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000176}
177
178
179bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000180 if (!this->IsHeapObject()) return false;
181 uint32_t type = HeapObject::cast(this)->map()->instance_type();
182 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
183 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000184}
185
186
ager@chromium.org870a0b62008-11-04 11:43:05 +0000187bool Object::IsSeqString() {
188 if (!IsString()) return false;
189 return StringShape(String::cast(this)).IsSequential();
190}
191
192
193bool Object::IsSeqAsciiString() {
194 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000195 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000196 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000197}
198
199
200bool Object::IsSeqTwoByteString() {
201 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000202 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000203 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000204}
205
206
207bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000208 if (!IsString()) return false;
209 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000210}
211
212
213bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000214 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000215 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000216 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000217}
218
219
220bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000221 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000222 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000223 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000224}
225
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000226bool Object::HasValidElements() {
227 // Dictionary is covered under FixedArray.
228 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
229}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000230
ager@chromium.org870a0b62008-11-04 11:43:05 +0000231StringShape::StringShape(String* str)
232 : type_(str->map()->instance_type()) {
233 set_valid();
234 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000235}
236
237
ager@chromium.org870a0b62008-11-04 11:43:05 +0000238StringShape::StringShape(Map* map)
239 : type_(map->instance_type()) {
240 set_valid();
241 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000242}
243
244
ager@chromium.org870a0b62008-11-04 11:43:05 +0000245StringShape::StringShape(InstanceType t)
246 : type_(static_cast<uint32_t>(t)) {
247 set_valid();
248 ASSERT((type_ & kIsNotStringMask) == kStringTag);
249}
250
251
252bool StringShape::IsSymbol() {
253 ASSERT(valid());
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000254 ASSERT(kSymbolTag != 0);
255 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000256}
257
258
ager@chromium.org5ec48922009-05-05 07:25:34 +0000259bool String::IsAsciiRepresentation() {
260 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000261 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000262}
263
264
ager@chromium.org5ec48922009-05-05 07:25:34 +0000265bool String::IsTwoByteRepresentation() {
266 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000267 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000268}
269
270
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000271bool String::HasOnlyAsciiChars() {
272 uint32_t type = map()->instance_type();
273 return (type & kStringEncodingMask) == kAsciiStringTag ||
274 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000275}
276
277
ager@chromium.org870a0b62008-11-04 11:43:05 +0000278bool StringShape::IsCons() {
279 return (type_ & kStringRepresentationMask) == kConsStringTag;
280}
281
282
ager@chromium.org870a0b62008-11-04 11:43:05 +0000283bool StringShape::IsExternal() {
284 return (type_ & kStringRepresentationMask) == kExternalStringTag;
285}
286
287
288bool StringShape::IsSequential() {
289 return (type_ & kStringRepresentationMask) == kSeqStringTag;
290}
291
292
293StringRepresentationTag StringShape::representation_tag() {
294 uint32_t tag = (type_ & kStringRepresentationMask);
295 return static_cast<StringRepresentationTag>(tag);
296}
297
298
299uint32_t StringShape::full_representation_tag() {
300 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
301}
302
303
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000304STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
305 Internals::kFullStringRepresentationMask);
306
307
ager@chromium.org870a0b62008-11-04 11:43:05 +0000308bool StringShape::IsSequentialAscii() {
309 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
310}
311
312
313bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000314 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000315}
316
317
318bool StringShape::IsExternalAscii() {
319 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
320}
321
322
323bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000324 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000325}
326
327
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000328STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
329 Internals::kExternalTwoByteRepresentationTag);
330
331
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000332uc32 FlatStringReader::Get(int index) {
333 ASSERT(0 <= index && index <= length_);
334 if (is_ascii_) {
335 return static_cast<const byte*>(start_)[index];
336 } else {
337 return static_cast<const uc16*>(start_)[index];
338 }
339}
340
341
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000342bool Object::IsNumber() {
343 return IsSmi() || IsHeapNumber();
344}
345
346
347bool Object::IsByteArray() {
348 return Object::IsHeapObject()
349 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
350}
351
352
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000353bool Object::IsExternalPixelArray() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000354 return Object::IsHeapObject() &&
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000355 HeapObject::cast(this)->map()->instance_type() ==
356 EXTERNAL_PIXEL_ARRAY_TYPE;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000357}
358
359
ager@chromium.org3811b432009-10-28 14:53:37 +0000360bool Object::IsExternalArray() {
361 if (!Object::IsHeapObject())
362 return false;
363 InstanceType instance_type =
364 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000365 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
366 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000367}
368
369
370bool Object::IsExternalByteArray() {
371 return Object::IsHeapObject() &&
372 HeapObject::cast(this)->map()->instance_type() ==
373 EXTERNAL_BYTE_ARRAY_TYPE;
374}
375
376
377bool Object::IsExternalUnsignedByteArray() {
378 return Object::IsHeapObject() &&
379 HeapObject::cast(this)->map()->instance_type() ==
380 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
381}
382
383
384bool Object::IsExternalShortArray() {
385 return Object::IsHeapObject() &&
386 HeapObject::cast(this)->map()->instance_type() ==
387 EXTERNAL_SHORT_ARRAY_TYPE;
388}
389
390
391bool Object::IsExternalUnsignedShortArray() {
392 return Object::IsHeapObject() &&
393 HeapObject::cast(this)->map()->instance_type() ==
394 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
395}
396
397
398bool Object::IsExternalIntArray() {
399 return Object::IsHeapObject() &&
400 HeapObject::cast(this)->map()->instance_type() ==
401 EXTERNAL_INT_ARRAY_TYPE;
402}
403
404
405bool Object::IsExternalUnsignedIntArray() {
406 return Object::IsHeapObject() &&
407 HeapObject::cast(this)->map()->instance_type() ==
408 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
409}
410
411
412bool Object::IsExternalFloatArray() {
413 return Object::IsHeapObject() &&
414 HeapObject::cast(this)->map()->instance_type() ==
415 EXTERNAL_FLOAT_ARRAY_TYPE;
416}
417
418
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000419bool Object::IsExternalDoubleArray() {
420 return Object::IsHeapObject() &&
421 HeapObject::cast(this)->map()->instance_type() ==
422 EXTERNAL_DOUBLE_ARRAY_TYPE;
423}
424
425
lrn@chromium.org303ada72010-10-27 09:33:13 +0000426bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000427 return HAS_FAILURE_TAG(this);
428}
429
430
lrn@chromium.org303ada72010-10-27 09:33:13 +0000431bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000432 return HAS_FAILURE_TAG(this)
433 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
434}
435
436
lrn@chromium.org303ada72010-10-27 09:33:13 +0000437bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000438 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000439 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000440}
441
442
lrn@chromium.org303ada72010-10-27 09:33:13 +0000443bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000444 return this == Failure::Exception();
445}
446
447
lrn@chromium.org303ada72010-10-27 09:33:13 +0000448bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000449 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000450}
451
452
453Failure* Failure::cast(MaybeObject* obj) {
454 ASSERT(HAS_FAILURE_TAG(obj));
455 return reinterpret_cast<Failure*>(obj);
456}
457
458
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000459bool Object::IsJSReceiver() {
460 return IsHeapObject() &&
461 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
462}
463
464
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000465bool Object::IsJSObject() {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000466 return IsJSReceiver() && !IsJSProxy();
467}
468
469
470bool Object::IsJSProxy() {
471 return Object::IsHeapObject() &&
472 (HeapObject::cast(this)->map()->instance_type() == JS_PROXY_TYPE ||
473 HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE);
474}
475
476
477bool Object::IsJSFunctionProxy() {
478 return Object::IsHeapObject() &&
479 HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000480}
481
482
ager@chromium.org32912102009-01-16 10:38:43 +0000483bool Object::IsJSContextExtensionObject() {
484 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000485 && (HeapObject::cast(this)->map()->instance_type() ==
486 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
ager@chromium.org32912102009-01-16 10:38:43 +0000487}
488
489
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000490bool Object::IsMap() {
491 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000492 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000493}
494
495
496bool Object::IsFixedArray() {
497 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000498 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000499}
500
501
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000502bool Object::IsFixedDoubleArray() {
503 return Object::IsHeapObject()
504 && HeapObject::cast(this)->map()->instance_type() ==
505 FIXED_DOUBLE_ARRAY_TYPE;
506}
507
508
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000509bool Object::IsDescriptorArray() {
510 return IsFixedArray();
511}
512
513
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000514bool Object::IsDeoptimizationInputData() {
515 // Must be a fixed array.
516 if (!IsFixedArray()) return false;
517
518 // There's no sure way to detect the difference between a fixed array and
519 // a deoptimization data array. Since this is used for asserts we can
520 // check that the length is zero or else the fixed size plus a multiple of
521 // the entry size.
522 int length = FixedArray::cast(this)->length();
523 if (length == 0) return true;
524
525 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
526 return length >= 0 &&
527 length % DeoptimizationInputData::kDeoptEntrySize == 0;
528}
529
530
531bool Object::IsDeoptimizationOutputData() {
532 if (!IsFixedArray()) return false;
533 // There's actually no way to see the difference between a fixed array and
534 // a deoptimization data array. Since this is used for asserts we can check
535 // that the length is plausible though.
536 if (FixedArray::cast(this)->length() % 2 != 0) return false;
537 return true;
538}
539
540
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000541bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000542 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000543 Map* map = HeapObject::cast(this)->map();
544 Heap* heap = map->GetHeap();
545 return (map == heap->function_context_map() ||
546 map == heap->catch_context_map() ||
547 map == heap->with_context_map() ||
548 map == heap->global_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000549 }
550 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000551}
552
553
554bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000555 return Object::IsHeapObject() &&
556 HeapObject::cast(this)->map() ==
557 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000558}
559
560
561bool Object::IsJSFunction() {
562 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000563 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000564}
565
566
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000567template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000568 return obj->IsJSFunction();
569}
570
571
572bool Object::IsCode() {
573 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000574 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000575}
576
577
578bool Object::IsOddball() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000579 ASSERT(HEAP->is_safe_to_read_maps());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000580 return Object::IsHeapObject()
581 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
582}
583
584
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000585bool Object::IsJSGlobalPropertyCell() {
586 return Object::IsHeapObject()
587 && HeapObject::cast(this)->map()->instance_type()
588 == JS_GLOBAL_PROPERTY_CELL_TYPE;
589}
590
591
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000592bool Object::IsSharedFunctionInfo() {
593 return Object::IsHeapObject() &&
594 (HeapObject::cast(this)->map()->instance_type() ==
595 SHARED_FUNCTION_INFO_TYPE);
596}
597
598
599bool Object::IsJSValue() {
600 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000601 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
602}
603
604
605bool Object::IsJSMessageObject() {
606 return Object::IsHeapObject()
607 && (HeapObject::cast(this)->map()->instance_type() ==
608 JS_MESSAGE_OBJECT_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000609}
610
611
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000612bool Object::IsStringWrapper() {
613 return IsJSValue() && JSValue::cast(this)->value()->IsString();
614}
615
616
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000617bool Object::IsForeign() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000618 return Object::IsHeapObject()
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000619 && HeapObject::cast(this)->map()->instance_type() == FOREIGN_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000620}
621
622
623bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000624 return IsOddball() &&
625 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000626}
627
628
629bool Object::IsJSArray() {
630 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000631 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000632}
633
634
ager@chromium.org236ad962008-09-25 09:45:57 +0000635bool Object::IsJSRegExp() {
636 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000637 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
ager@chromium.org236ad962008-09-25 09:45:57 +0000638}
639
640
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000641template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000642 return obj->IsJSArray();
643}
644
645
646bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000647 return Object::IsHeapObject() &&
648 HeapObject::cast(this)->map() ==
649 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000650}
651
652
653bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000654 return IsHashTable() &&
655 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000656}
657
658
659bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000660 return IsHashTable() && this ==
661 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000662}
663
664
ager@chromium.orgac091b72010-05-05 07:34:42 +0000665bool Object::IsJSFunctionResultCache() {
666 if (!IsFixedArray()) return false;
667 FixedArray* self = FixedArray::cast(this);
668 int length = self->length();
669 if (length < JSFunctionResultCache::kEntriesIndex) return false;
670 if ((length - JSFunctionResultCache::kEntriesIndex)
671 % JSFunctionResultCache::kEntrySize != 0) {
672 return false;
673 }
674#ifdef DEBUG
675 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
676#endif
677 return true;
678}
679
680
ricow@chromium.org65fae842010-08-25 15:26:24 +0000681bool Object::IsNormalizedMapCache() {
682 if (!IsFixedArray()) return false;
683 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
684 return false;
685 }
686#ifdef DEBUG
687 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
688#endif
689 return true;
690}
691
692
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000693bool Object::IsCompilationCacheTable() {
694 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000695}
696
697
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000698bool Object::IsCodeCacheHashTable() {
699 return IsHashTable();
700}
701
702
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000703bool Object::IsPolymorphicCodeCacheHashTable() {
704 return IsHashTable();
705}
706
707
ager@chromium.org236ad962008-09-25 09:45:57 +0000708bool Object::IsMapCache() {
709 return IsHashTable();
710}
711
712
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000713bool Object::IsPrimitive() {
714 return IsOddball() || IsNumber() || IsString();
715}
716
717
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000718bool Object::IsJSGlobalProxy() {
719 bool result = IsHeapObject() &&
720 (HeapObject::cast(this)->map()->instance_type() ==
721 JS_GLOBAL_PROXY_TYPE);
722 ASSERT(!result || IsAccessCheckNeeded());
723 return result;
724}
725
726
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000727bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000728 if (!IsHeapObject()) return false;
729
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000730 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000731 return type == JS_GLOBAL_OBJECT_TYPE ||
732 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000733}
734
735
736bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000737 return IsHeapObject() &&
738 (HeapObject::cast(this)->map()->instance_type() ==
739 JS_GLOBAL_OBJECT_TYPE);
740}
741
742
743bool Object::IsJSBuiltinsObject() {
744 return IsHeapObject() &&
745 (HeapObject::cast(this)->map()->instance_type() ==
746 JS_BUILTINS_OBJECT_TYPE);
747}
748
749
750bool Object::IsUndetectableObject() {
751 return IsHeapObject()
752 && HeapObject::cast(this)->map()->is_undetectable();
753}
754
755
756bool Object::IsAccessCheckNeeded() {
757 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000758 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000759}
760
761
762bool Object::IsStruct() {
763 if (!IsHeapObject()) return false;
764 switch (HeapObject::cast(this)->map()->instance_type()) {
765#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
766 STRUCT_LIST(MAKE_STRUCT_CASE)
767#undef MAKE_STRUCT_CASE
768 default: return false;
769 }
770}
771
772
773#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
774 bool Object::Is##Name() { \
775 return Object::IsHeapObject() \
776 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
777 }
778 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
779#undef MAKE_STRUCT_PREDICATE
780
781
782bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000783 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000784}
785
786
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000787bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000788 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
789}
790
791
792bool Object::IsTheHole() {
793 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000794}
795
796
797bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000798 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000799}
800
801
802bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000803 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000804}
805
806
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000807bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000808 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000809}
810
811
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000812double Object::Number() {
813 ASSERT(IsNumber());
814 return IsSmi()
815 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
816 : reinterpret_cast<HeapNumber*>(this)->value();
817}
818
819
lrn@chromium.org303ada72010-10-27 09:33:13 +0000820MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000821 if (IsSmi()) return this;
822 if (IsHeapNumber()) {
823 double value = HeapNumber::cast(this)->value();
824 int int_value = FastD2I(value);
825 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
826 return Smi::FromInt(int_value);
827 }
828 }
829 return Failure::Exception();
830}
831
832
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000833bool Object::HasSpecificClassOf(String* name) {
834 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
835}
836
837
lrn@chromium.org303ada72010-10-27 09:33:13 +0000838MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000839 // GetElement can trigger a getter which can cause allocation.
840 // This was not always the case. This ASSERT is here to catch
841 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000842 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000843 return GetElementWithReceiver(this, index);
844}
845
846
lrn@chromium.org303ada72010-10-27 09:33:13 +0000847Object* Object::GetElementNoExceptionThrown(uint32_t index) {
848 MaybeObject* maybe = GetElementWithReceiver(this, index);
849 ASSERT(!maybe->IsFailure());
850 Object* result = NULL; // Initialization to please compiler.
851 maybe->ToObject(&result);
852 return result;
853}
854
855
856MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000857 PropertyAttributes attributes;
858 return GetPropertyWithReceiver(this, key, &attributes);
859}
860
861
lrn@chromium.org303ada72010-10-27 09:33:13 +0000862MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000863 return GetPropertyWithReceiver(this, key, attributes);
864}
865
866
867#define FIELD_ADDR(p, offset) \
868 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
869
870#define READ_FIELD(p, offset) \
871 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
872
873#define WRITE_FIELD(p, offset, value) \
874 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
875
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000876// TODO(isolates): Pass heap in to these macros.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000877#define WRITE_BARRIER(object, offset) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000878 object->GetHeap()->RecordWrite(object->address(), offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000879
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000880// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000881// write due to the assert validating the written value.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000882#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, mode) \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000883 if (mode == UPDATE_WRITE_BARRIER) { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000884 heap->RecordWrite(object->address(), offset); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000885 } else { \
886 ASSERT(mode == SKIP_WRITE_BARRIER); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000887 ASSERT(heap->InNewSpace(object) || \
888 !heap->InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000889 Page::FromAddress(object->address())-> \
890 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000891 }
892
lrn@chromium.org7516f052011-03-30 08:52:27 +0000893#ifndef V8_TARGET_ARCH_MIPS
894 #define READ_DOUBLE_FIELD(p, offset) \
895 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
896#else // V8_TARGET_ARCH_MIPS
897 // Prevent gcc from using load-double (mips ldc1) on (possibly)
898 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000899 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000900 union conversion {
901 double d;
902 uint32_t u[2];
903 } c;
904 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
905 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
906 return c.d;
907 }
908 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
909#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000910
lrn@chromium.org7516f052011-03-30 08:52:27 +0000911
912#ifndef V8_TARGET_ARCH_MIPS
913 #define WRITE_DOUBLE_FIELD(p, offset, value) \
914 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
915#else // V8_TARGET_ARCH_MIPS
916 // Prevent gcc from using store-double (mips sdc1) on (possibly)
917 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000918 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000919 double value) {
920 union conversion {
921 double d;
922 uint32_t u[2];
923 } c;
924 c.d = value;
925 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
926 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
927 }
928 #define WRITE_DOUBLE_FIELD(p, offset, value) \
929 write_double_field(p, offset, value)
930#endif // V8_TARGET_ARCH_MIPS
931
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000932
933#define READ_INT_FIELD(p, offset) \
934 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
935
936#define WRITE_INT_FIELD(p, offset, value) \
937 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
938
ager@chromium.org3e875802009-06-29 08:26:34 +0000939#define READ_INTPTR_FIELD(p, offset) \
940 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
941
942#define WRITE_INTPTR_FIELD(p, offset, value) \
943 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
944
ager@chromium.org7c537e22008-10-16 08:43:32 +0000945#define READ_UINT32_FIELD(p, offset) \
946 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
947
948#define WRITE_UINT32_FIELD(p, offset, value) \
949 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
950
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000951#define READ_SHORT_FIELD(p, offset) \
952 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
953
954#define WRITE_SHORT_FIELD(p, offset, value) \
955 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
956
957#define READ_BYTE_FIELD(p, offset) \
958 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
959
960#define WRITE_BYTE_FIELD(p, offset, value) \
961 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
962
963
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000964Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
965 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000966}
967
968
969int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000970 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000971}
972
973
974Smi* Smi::FromInt(int value) {
975 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000976 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000977 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000978 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000979 return reinterpret_cast<Smi*>(tagged_value);
980}
981
982
983Smi* Smi::FromIntptr(intptr_t value) {
984 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000985 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
986 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000987}
988
989
990Failure::Type Failure::type() const {
991 return static_cast<Type>(value() & kFailureTypeTagMask);
992}
993
994
995bool Failure::IsInternalError() const {
996 return type() == INTERNAL_ERROR;
997}
998
999
1000bool Failure::IsOutOfMemoryException() const {
1001 return type() == OUT_OF_MEMORY_EXCEPTION;
1002}
1003
1004
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001005AllocationSpace Failure::allocation_space() const {
1006 ASSERT_EQ(RETRY_AFTER_GC, type());
1007 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1008 & kSpaceTagMask);
1009}
1010
1011
1012Failure* Failure::InternalError() {
1013 return Construct(INTERNAL_ERROR);
1014}
1015
1016
1017Failure* Failure::Exception() {
1018 return Construct(EXCEPTION);
1019}
1020
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001021
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001022Failure* Failure::OutOfMemoryException() {
1023 return Construct(OUT_OF_MEMORY_EXCEPTION);
1024}
1025
1026
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001027intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001028 return static_cast<intptr_t>(
1029 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001030}
1031
1032
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001033Failure* Failure::RetryAfterGC() {
1034 return RetryAfterGC(NEW_SPACE);
1035}
1036
1037
1038Failure* Failure::RetryAfterGC(AllocationSpace space) {
1039 ASSERT((space & ~kSpaceTagMask) == 0);
1040 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001041}
1042
1043
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001044Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001045 uintptr_t info =
1046 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001047 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001048 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001049}
1050
1051
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001052bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001053#ifdef DEBUG
1054 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1055#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001056
1057#ifdef V8_TARGET_ARCH_X64
1058 // To be representable as a long smi, the value must be a 32-bit integer.
1059 bool result = (value == static_cast<int32_t>(value));
1060#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001061 // To be representable as an tagged small integer, the two
1062 // most-significant bits of 'value' must be either 00 or 11 due to
1063 // sign-extension. To check this we add 01 to the two
1064 // most-significant bits, and check if the most-significant bit is 0
1065 //
1066 // CAUTION: The original code below:
1067 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1068 // may lead to incorrect results according to the C language spec, and
1069 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1070 // compiler may produce undefined results in case of signed integer
1071 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001072 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001073#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001074 ASSERT(result == in_range);
1075 return result;
1076}
1077
1078
kasper.lund7276f142008-07-30 08:49:36 +00001079MapWord MapWord::FromMap(Map* map) {
1080 return MapWord(reinterpret_cast<uintptr_t>(map));
1081}
1082
1083
1084Map* MapWord::ToMap() {
1085 return reinterpret_cast<Map*>(value_);
1086}
1087
1088
1089bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001090 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001091}
1092
1093
1094MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001095 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1096 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001097}
1098
1099
1100HeapObject* MapWord::ToForwardingAddress() {
1101 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001102 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001103}
1104
1105
1106bool MapWord::IsMarked() {
1107 return (value_ & kMarkingMask) == 0;
1108}
1109
1110
1111void MapWord::SetMark() {
1112 value_ &= ~kMarkingMask;
1113}
1114
1115
1116void MapWord::ClearMark() {
1117 value_ |= kMarkingMask;
1118}
1119
1120
1121bool MapWord::IsOverflowed() {
1122 return (value_ & kOverflowMask) != 0;
1123}
1124
1125
1126void MapWord::SetOverflow() {
1127 value_ |= kOverflowMask;
1128}
1129
1130
1131void MapWord::ClearOverflow() {
1132 value_ &= ~kOverflowMask;
1133}
1134
1135
1136MapWord MapWord::EncodeAddress(Address map_address, int offset) {
1137 // Offset is the distance in live bytes from the first live object in the
1138 // same page. The offset between two objects in the same page should not
1139 // exceed the object area size of a page.
1140 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1141
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001142 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001143 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1144
1145 Page* map_page = Page::FromAddress(map_address);
1146 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1147
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001148 uintptr_t map_page_offset =
1149 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001150
1151 uintptr_t encoding =
1152 (compact_offset << kForwardingOffsetShift) |
1153 (map_page_offset << kMapPageOffsetShift) |
1154 (map_page->mc_page_index << kMapPageIndexShift);
1155 return MapWord(encoding);
1156}
1157
1158
1159Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001160 int map_page_index =
1161 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001162 ASSERT_MAP_PAGE_INDEX(map_page_index);
1163
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001164 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001165 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1166 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001167
1168 return (map_space->PageAddress(map_page_index) + map_page_offset);
1169}
1170
1171
1172int MapWord::DecodeOffset() {
1173 // The offset field is represented in the kForwardingOffsetBits
1174 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001175 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1176 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1177 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001178}
1179
1180
1181MapWord MapWord::FromEncodedAddress(Address address) {
1182 return MapWord(reinterpret_cast<uintptr_t>(address));
1183}
1184
1185
1186Address MapWord::ToEncodedAddress() {
1187 return reinterpret_cast<Address>(value_);
1188}
1189
1190
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001191#ifdef DEBUG
1192void HeapObject::VerifyObjectField(int offset) {
1193 VerifyPointer(READ_FIELD(this, offset));
1194}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001195
1196void HeapObject::VerifySmiField(int offset) {
1197 ASSERT(READ_FIELD(this, offset)->IsSmi());
1198}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001199#endif
1200
1201
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001202Heap* HeapObject::GetHeap() {
1203 // During GC, the map pointer in HeapObject is used in various ways that
1204 // prevent us from retrieving Heap from the map.
1205 // Assert that we are not in GC, implement GC code in a way that it doesn't
1206 // pull heap from the map.
1207 ASSERT(HEAP->is_safe_to_read_maps());
1208 return map()->heap();
1209}
1210
1211
1212Isolate* HeapObject::GetIsolate() {
1213 return GetHeap()->isolate();
1214}
1215
1216
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001217Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001218 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001219}
1220
1221
1222void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001223 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001224}
1225
1226
kasper.lund7276f142008-07-30 08:49:36 +00001227MapWord HeapObject::map_word() {
1228 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1229}
1230
1231
1232void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001233 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001234 // here.
1235 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1236}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001237
1238
1239HeapObject* HeapObject::FromAddress(Address address) {
1240 ASSERT_TAG_ALIGNED(address);
1241 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1242}
1243
1244
1245Address HeapObject::address() {
1246 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1247}
1248
1249
1250int HeapObject::Size() {
1251 return SizeFromMap(map());
1252}
1253
1254
1255void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1256 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1257 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1258}
1259
1260
1261void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1262 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1263}
1264
1265
kasper.lund7276f142008-07-30 08:49:36 +00001266bool HeapObject::IsMarked() {
1267 return map_word().IsMarked();
1268}
1269
1270
1271void HeapObject::SetMark() {
1272 ASSERT(!IsMarked());
1273 MapWord first_word = map_word();
1274 first_word.SetMark();
1275 set_map_word(first_word);
1276}
1277
1278
1279void HeapObject::ClearMark() {
1280 ASSERT(IsMarked());
1281 MapWord first_word = map_word();
1282 first_word.ClearMark();
1283 set_map_word(first_word);
1284}
1285
1286
1287bool HeapObject::IsOverflowed() {
1288 return map_word().IsOverflowed();
1289}
1290
1291
1292void HeapObject::SetOverflow() {
1293 MapWord first_word = map_word();
1294 first_word.SetOverflow();
1295 set_map_word(first_word);
1296}
1297
1298
1299void HeapObject::ClearOverflow() {
1300 ASSERT(IsOverflowed());
1301 MapWord first_word = map_word();
1302 first_word.ClearOverflow();
1303 set_map_word(first_word);
1304}
1305
1306
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001307double HeapNumber::value() {
1308 return READ_DOUBLE_FIELD(this, kValueOffset);
1309}
1310
1311
1312void HeapNumber::set_value(double value) {
1313 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1314}
1315
1316
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001317int HeapNumber::get_exponent() {
1318 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1319 kExponentShift) - kExponentBias;
1320}
1321
1322
1323int HeapNumber::get_sign() {
1324 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1325}
1326
1327
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001328ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001329
1330
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001331HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001332 Object* array = READ_FIELD(this, kElementsOffset);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001333 ASSERT(array->HasValidElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001334 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001335}
1336
1337
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001338void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001339 ASSERT(map()->has_fast_elements() ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001340 (value->map() == GetHeap()->fixed_array_map() ||
1341 value->map() == GetHeap()->fixed_cow_array_map()));
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001342 ASSERT(value->HasValidElements());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001343 WRITE_FIELD(this, kElementsOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001344 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001345}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001346
1347
1348void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001349 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1350 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001351}
1352
1353
1354void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001355 ASSERT(map()->has_fast_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001356 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1357 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001358}
1359
1360
lrn@chromium.org303ada72010-10-27 09:33:13 +00001361MaybeObject* JSObject::ResetElements() {
1362 Object* obj;
1363 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
1364 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1365 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001366 set_map(Map::cast(obj));
1367 initialize_elements();
1368 return this;
1369}
1370
1371
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001372ACCESSORS(Oddball, to_string, String, kToStringOffset)
1373ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1374
1375
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001376byte Oddball::kind() {
1377 return READ_BYTE_FIELD(this, kKindOffset);
1378}
1379
1380
1381void Oddball::set_kind(byte value) {
1382 WRITE_BYTE_FIELD(this, kKindOffset, value);
1383}
1384
1385
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001386Object* JSGlobalPropertyCell::value() {
1387 return READ_FIELD(this, kValueOffset);
1388}
1389
1390
1391void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1392 // The write barrier is not used for global property cells.
1393 ASSERT(!val->IsJSGlobalPropertyCell());
1394 WRITE_FIELD(this, kValueOffset, val);
1395}
1396
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001397
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001398int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001399 InstanceType type = map()->instance_type();
1400 // Check for the most common kind of JavaScript object before
1401 // falling into the generic switch. This speeds up the internal
1402 // field operations considerably on average.
1403 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1404 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001405 case JS_GLOBAL_PROXY_TYPE:
1406 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001407 case JS_GLOBAL_OBJECT_TYPE:
1408 return JSGlobalObject::kSize;
1409 case JS_BUILTINS_OBJECT_TYPE:
1410 return JSBuiltinsObject::kSize;
1411 case JS_FUNCTION_TYPE:
1412 return JSFunction::kSize;
1413 case JS_VALUE_TYPE:
1414 return JSValue::kSize;
1415 case JS_ARRAY_TYPE:
1416 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001417 case JS_REGEXP_TYPE:
1418 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001419 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001420 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001421 case JS_MESSAGE_OBJECT_TYPE:
1422 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001423 default:
1424 UNREACHABLE();
1425 return 0;
1426 }
1427}
1428
1429
1430int JSObject::GetInternalFieldCount() {
1431 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001432 // Make sure to adjust for the number of in-object properties. These
1433 // properties do contribute to the size, but are not internal fields.
1434 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1435 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001436}
1437
1438
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001439int JSObject::GetInternalFieldOffset(int index) {
1440 ASSERT(index < GetInternalFieldCount() && index >= 0);
1441 return GetHeaderSize() + (kPointerSize * index);
1442}
1443
1444
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001445Object* JSObject::GetInternalField(int index) {
1446 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001447 // Internal objects do follow immediately after the header, whereas in-object
1448 // properties are at the end of the object. Therefore there is no need
1449 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001450 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1451}
1452
1453
1454void JSObject::SetInternalField(int index, Object* value) {
1455 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001456 // Internal objects do follow immediately after the header, whereas in-object
1457 // properties are at the end of the object. Therefore there is no need
1458 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001459 int offset = GetHeaderSize() + (kPointerSize * index);
1460 WRITE_FIELD(this, offset, value);
1461 WRITE_BARRIER(this, offset);
1462}
1463
1464
ager@chromium.org7c537e22008-10-16 08:43:32 +00001465// Access fast-case object properties at index. The use of these routines
1466// is needed to correctly distinguish between properties stored in-object and
1467// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001468Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001469 // Adjust for the number of properties stored in the object.
1470 index -= map()->inobject_properties();
1471 if (index < 0) {
1472 int offset = map()->instance_size() + (index * kPointerSize);
1473 return READ_FIELD(this, offset);
1474 } else {
1475 ASSERT(index < properties()->length());
1476 return properties()->get(index);
1477 }
1478}
1479
1480
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001481Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001482 // Adjust for the number of properties stored in the object.
1483 index -= map()->inobject_properties();
1484 if (index < 0) {
1485 int offset = map()->instance_size() + (index * kPointerSize);
1486 WRITE_FIELD(this, offset, value);
1487 WRITE_BARRIER(this, offset);
1488 } else {
1489 ASSERT(index < properties()->length());
1490 properties()->set(index, value);
1491 }
1492 return value;
1493}
1494
1495
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001496int JSObject::GetInObjectPropertyOffset(int index) {
1497 // Adjust for the number of properties stored in the object.
1498 index -= map()->inobject_properties();
1499 ASSERT(index < 0);
1500 return map()->instance_size() + (index * kPointerSize);
1501}
1502
1503
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001504Object* JSObject::InObjectPropertyAt(int index) {
1505 // Adjust for the number of properties stored in the object.
1506 index -= map()->inobject_properties();
1507 ASSERT(index < 0);
1508 int offset = map()->instance_size() + (index * kPointerSize);
1509 return READ_FIELD(this, offset);
1510}
1511
1512
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001513Object* JSObject::InObjectPropertyAtPut(int index,
1514 Object* value,
1515 WriteBarrierMode mode) {
1516 // Adjust for the number of properties stored in the object.
1517 index -= map()->inobject_properties();
1518 ASSERT(index < 0);
1519 int offset = map()->instance_size() + (index * kPointerSize);
1520 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001521 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001522 return value;
1523}
1524
1525
1526
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001527void JSObject::InitializeBody(int object_size, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001528 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001529 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001530 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001531 }
1532}
1533
1534
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001535bool JSObject::HasFastProperties() {
1536 return !properties()->IsDictionary();
1537}
1538
1539
1540int JSObject::MaxFastProperties() {
1541 // Allow extra fast properties if the object has more than
1542 // kMaxFastProperties in-object properties. When this is the case,
1543 // it is very unlikely that the object is being used as a dictionary
1544 // and there is a good chance that allowing more map transitions
1545 // will be worth it.
1546 return Max(map()->inobject_properties(), kMaxFastProperties);
1547}
1548
1549
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001550void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001551 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001552 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001553 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001554 }
1555}
1556
1557
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001558bool Object::ToArrayIndex(uint32_t* index) {
1559 if (IsSmi()) {
1560 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001561 if (value < 0) return false;
1562 *index = value;
1563 return true;
1564 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001565 if (IsHeapNumber()) {
1566 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001567 uint32_t uint_value = static_cast<uint32_t>(value);
1568 if (value == static_cast<double>(uint_value)) {
1569 *index = uint_value;
1570 return true;
1571 }
1572 }
1573 return false;
1574}
1575
1576
1577bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1578 if (!this->IsJSValue()) return false;
1579
1580 JSValue* js_value = JSValue::cast(this);
1581 if (!js_value->value()->IsString()) return false;
1582
1583 String* str = String::cast(js_value->value());
1584 if (index >= (uint32_t)str->length()) return false;
1585
1586 return true;
1587}
1588
1589
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001590FixedArrayBase* FixedArrayBase::cast(Object* object) {
1591 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1592 return reinterpret_cast<FixedArrayBase*>(object);
1593}
1594
1595
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001596Object* FixedArray::get(int index) {
1597 ASSERT(index >= 0 && index < this->length());
1598 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1599}
1600
1601
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001602void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001603 ASSERT(map() != HEAP->fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001604 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1605 int offset = kHeaderSize + index * kPointerSize;
1606 WRITE_FIELD(this, offset, value);
1607}
1608
1609
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001610void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001611 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001612 ASSERT(index >= 0 && index < this->length());
1613 int offset = kHeaderSize + index * kPointerSize;
1614 WRITE_FIELD(this, offset, value);
1615 WRITE_BARRIER(this, offset);
1616}
1617
1618
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001619inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1620 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1621}
1622
1623
1624inline double FixedDoubleArray::hole_nan_as_double() {
1625 return BitCast<double, uint64_t>(kHoleNanInt64);
1626}
1627
1628
1629inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1630 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1631 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1632 return OS::nan_value();
1633}
1634
1635
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001636double FixedDoubleArray::get(int index) {
1637 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1638 map() != HEAP->fixed_array_map());
1639 ASSERT(index >= 0 && index < this->length());
1640 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1641 ASSERT(!is_the_hole_nan(result));
1642 return result;
1643}
1644
1645
1646void FixedDoubleArray::set(int index, double value) {
1647 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1648 map() != HEAP->fixed_array_map());
1649 int offset = kHeaderSize + index * kDoubleSize;
1650 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1651 WRITE_DOUBLE_FIELD(this, offset, value);
1652}
1653
1654
1655void FixedDoubleArray::set_the_hole(int index) {
1656 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1657 map() != HEAP->fixed_array_map());
1658 int offset = kHeaderSize + index * kDoubleSize;
1659 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1660}
1661
1662
1663bool FixedDoubleArray::is_the_hole(int index) {
1664 int offset = kHeaderSize + index * kDoubleSize;
1665 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1666}
1667
1668
1669void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1670 int old_length = from->length();
1671 ASSERT(old_length < length());
1672 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1673 FIELD_ADDR(from, kHeaderSize),
1674 old_length * kDoubleSize);
1675 int offset = kHeaderSize + old_length * kDoubleSize;
1676 for (int current = from->length(); current < length(); ++current) {
1677 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1678 offset += kDoubleSize;
1679 }
1680}
1681
1682
1683void FixedDoubleArray::Initialize(FixedArray* from) {
1684 int old_length = from->length();
1685 ASSERT(old_length < length());
1686 for (int i = 0; i < old_length; i++) {
1687 Object* hole_or_object = from->get(i);
1688 if (hole_or_object->IsTheHole()) {
1689 set_the_hole(i);
1690 } else {
1691 set(i, hole_or_object->Number());
1692 }
1693 }
1694 int offset = kHeaderSize + old_length * kDoubleSize;
1695 for (int current = from->length(); current < length(); ++current) {
1696 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1697 offset += kDoubleSize;
1698 }
1699}
1700
1701
1702void FixedDoubleArray::Initialize(NumberDictionary* from) {
1703 int offset = kHeaderSize;
1704 for (int current = 0; current < length(); ++current) {
1705 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1706 offset += kDoubleSize;
1707 }
1708 for (int i = 0; i < from->Capacity(); i++) {
1709 Object* key = from->KeyAt(i);
1710 if (key->IsNumber()) {
1711 uint32_t entry = static_cast<uint32_t>(key->Number());
1712 set(entry, from->ValueAt(i)->Number());
1713 }
1714 }
1715}
1716
1717
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001718WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001719 if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001720 return UPDATE_WRITE_BARRIER;
1721}
1722
1723
1724void FixedArray::set(int index,
1725 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001726 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001727 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001728 ASSERT(index >= 0 && index < this->length());
1729 int offset = kHeaderSize + index * kPointerSize;
1730 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001731 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001732}
1733
1734
1735void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001736 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001737 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001738 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001739 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1740}
1741
1742
1743void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001744 ASSERT(map() != HEAP->fixed_cow_array_map());
1745 set_undefined(GetHeap(), index);
1746}
1747
1748
1749void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001750 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001751 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001752 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001753 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001754}
1755
1756
ager@chromium.org236ad962008-09-25 09:45:57 +00001757void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001758 set_null(GetHeap(), index);
1759}
1760
1761
1762void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001763 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001764 ASSERT(!heap->InNewSpace(heap->null_value()));
1765 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001766}
1767
1768
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001769void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001770 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001771 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001772 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1773 WRITE_FIELD(this,
1774 kHeaderSize + index * kPointerSize,
1775 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001776}
1777
1778
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001779void FixedArray::set_unchecked(int index, Smi* value) {
1780 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1781 int offset = kHeaderSize + index * kPointerSize;
1782 WRITE_FIELD(this, offset, value);
1783}
1784
1785
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001786void FixedArray::set_unchecked(Heap* heap,
1787 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001788 Object* value,
1789 WriteBarrierMode mode) {
1790 int offset = kHeaderSize + index * kPointerSize;
1791 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001792 CONDITIONAL_WRITE_BARRIER(heap, this, offset, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001793}
1794
1795
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001796void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001797 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001798 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1799 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001800}
1801
1802
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001803Object** FixedArray::data_start() {
1804 return HeapObject::RawField(this, kHeaderSize);
1805}
1806
1807
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001808bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001809 ASSERT(this->IsSmi() ||
1810 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001811 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001812 return this->IsSmi() || length() <= kFirstIndex;
1813}
1814
1815
1816int DescriptorArray::bit_field3_storage() {
1817 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1818 return Smi::cast(storage)->value();
1819}
1820
1821void DescriptorArray::set_bit_field3_storage(int value) {
1822 ASSERT(!IsEmpty());
1823 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001824}
1825
1826
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001827void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1828 Object* tmp = array->get(first);
1829 fast_set(array, first, array->get(second));
1830 fast_set(array, second, tmp);
1831}
1832
1833
1834int DescriptorArray::Search(String* name) {
1835 SLOW_ASSERT(IsSortedNoDuplicates());
1836
1837 // Check for empty descriptor array.
1838 int nof = number_of_descriptors();
1839 if (nof == 0) return kNotFound;
1840
1841 // Fast case: do linear search for small arrays.
1842 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001843 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001844 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001845 }
1846
1847 // Slow case: perform binary search.
1848 return BinarySearch(name, 0, nof - 1);
1849}
1850
1851
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001852int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001853 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001854 if (number == DescriptorLookupCache::kAbsent) {
1855 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001856 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001857 }
1858 return number;
1859}
1860
1861
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001862String* DescriptorArray::GetKey(int descriptor_number) {
1863 ASSERT(descriptor_number < number_of_descriptors());
1864 return String::cast(get(ToKeyIndex(descriptor_number)));
1865}
1866
1867
1868Object* DescriptorArray::GetValue(int descriptor_number) {
1869 ASSERT(descriptor_number < number_of_descriptors());
1870 return GetContentArray()->get(ToValueIndex(descriptor_number));
1871}
1872
1873
1874Smi* DescriptorArray::GetDetails(int descriptor_number) {
1875 ASSERT(descriptor_number < number_of_descriptors());
1876 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1877}
1878
1879
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001880PropertyType DescriptorArray::GetType(int descriptor_number) {
1881 ASSERT(descriptor_number < number_of_descriptors());
1882 return PropertyDetails(GetDetails(descriptor_number)).type();
1883}
1884
1885
1886int DescriptorArray::GetFieldIndex(int descriptor_number) {
1887 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1888}
1889
1890
1891JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1892 return JSFunction::cast(GetValue(descriptor_number));
1893}
1894
1895
1896Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1897 ASSERT(GetType(descriptor_number) == CALLBACKS);
1898 return GetValue(descriptor_number);
1899}
1900
1901
1902AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1903 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001904 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
1905 return reinterpret_cast<AccessorDescriptor*>(p->address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001906}
1907
1908
1909bool DescriptorArray::IsProperty(int descriptor_number) {
1910 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1911}
1912
1913
1914bool DescriptorArray::IsTransition(int descriptor_number) {
1915 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001916 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
1917 t == EXTERNAL_ARRAY_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001918}
1919
1920
1921bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1922 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1923}
1924
1925
1926bool DescriptorArray::IsDontEnum(int descriptor_number) {
1927 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1928}
1929
1930
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001931void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1932 desc->Init(GetKey(descriptor_number),
1933 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001934 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001935}
1936
1937
1938void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1939 // Range check.
1940 ASSERT(descriptor_number < number_of_descriptors());
1941
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001942 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001943 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1944 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001945
1946 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1947 FixedArray* content_array = GetContentArray();
1948 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1949 fast_set(content_array, ToDetailsIndex(descriptor_number),
1950 desc->GetDetails().AsSmi());
1951}
1952
1953
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001954void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1955 Descriptor desc;
1956 src->Get(src_index, &desc);
1957 Set(index, &desc);
1958}
1959
1960
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001961void DescriptorArray::Swap(int first, int second) {
1962 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1963 FixedArray* content_array = GetContentArray();
1964 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1965 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1966}
1967
1968
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001969template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001970int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
1971 const int kMinCapacity = 32;
1972 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
1973 if (capacity < kMinCapacity) {
1974 capacity = kMinCapacity; // Guarantee min capacity.
1975 }
1976 return capacity;
1977}
1978
1979
1980template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001981int HashTable<Shape, Key>::FindEntry(Key key) {
1982 return FindEntry(GetIsolate(), key);
1983}
1984
1985
1986// Find entry for key otherwise return kNotFound.
1987template<typename Shape, typename Key>
1988int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
1989 uint32_t capacity = Capacity();
1990 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
1991 uint32_t count = 1;
1992 // EnsureCapacity will guarantee the hash table is never full.
1993 while (true) {
1994 Object* element = KeyAt(entry);
1995 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
1996 if (element != isolate->heap()->null_value() &&
1997 Shape::IsMatch(key, element)) return entry;
1998 entry = NextProbe(entry, count++, capacity);
1999 }
2000 return kNotFound;
2001}
2002
2003
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002004bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002005 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002006 if (!max_index_object->IsSmi()) return false;
2007 return 0 !=
2008 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2009}
2010
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002011uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002012 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002013 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002014 if (!max_index_object->IsSmi()) return 0;
2015 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2016 return value >> kRequiresSlowElementsTagSize;
2017}
2018
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002019void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002020 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002021}
2022
2023
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002024// ------------------------------------
2025// Cast operations
2026
2027
2028CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002029CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002030CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002031CAST_ACCESSOR(DeoptimizationInputData)
2032CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002033CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002034CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002035CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002036CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002037CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002038CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002039CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002040CAST_ACCESSOR(String)
2041CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002042CAST_ACCESSOR(SeqAsciiString)
2043CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002044CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002045CAST_ACCESSOR(ExternalString)
2046CAST_ACCESSOR(ExternalAsciiString)
2047CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002048CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002049CAST_ACCESSOR(JSObject)
2050CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002051CAST_ACCESSOR(HeapObject)
2052CAST_ACCESSOR(HeapNumber)
2053CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002054CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002055CAST_ACCESSOR(SharedFunctionInfo)
2056CAST_ACCESSOR(Map)
2057CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002058CAST_ACCESSOR(GlobalObject)
2059CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002060CAST_ACCESSOR(JSGlobalObject)
2061CAST_ACCESSOR(JSBuiltinsObject)
2062CAST_ACCESSOR(Code)
2063CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002064CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002065CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002066CAST_ACCESSOR(JSFunctionProxy)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002067CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002068CAST_ACCESSOR(ByteArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00002069CAST_ACCESSOR(ExternalArray)
2070CAST_ACCESSOR(ExternalByteArray)
2071CAST_ACCESSOR(ExternalUnsignedByteArray)
2072CAST_ACCESSOR(ExternalShortArray)
2073CAST_ACCESSOR(ExternalUnsignedShortArray)
2074CAST_ACCESSOR(ExternalIntArray)
2075CAST_ACCESSOR(ExternalUnsignedIntArray)
2076CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002077CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002078CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002079CAST_ACCESSOR(Struct)
2080
2081
2082#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2083 STRUCT_LIST(MAKE_STRUCT_CAST)
2084#undef MAKE_STRUCT_CAST
2085
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002086
2087template <typename Shape, typename Key>
2088HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002089 ASSERT(obj->IsHashTable());
2090 return reinterpret_cast<HashTable*>(obj);
2091}
2092
2093
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002094SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002095SMI_ACCESSORS(ByteArray, length, kLengthOffset)
2096
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00002097// TODO(1493): Investigate if it's possible to s/INT/SMI/ here (and
whesse@chromium.org7b260152011-06-20 15:33:18 +00002098// subsequently unify H{Fixed,External}ArrayLength).
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002099INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002100
2101
ager@chromium.orgac091b72010-05-05 07:34:42 +00002102SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002103
2104
2105uint32_t String::hash_field() {
2106 return READ_UINT32_FIELD(this, kHashFieldOffset);
2107}
2108
2109
2110void String::set_hash_field(uint32_t value) {
2111 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002112#if V8_HOST_ARCH_64_BIT
2113 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2114#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002115}
2116
2117
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002118bool String::Equals(String* other) {
2119 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002120 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2121 return false;
2122 }
2123 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002124}
2125
2126
lrn@chromium.org303ada72010-10-27 09:33:13 +00002127MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002128 if (!StringShape(this).IsCons()) return this;
2129 ConsString* cons = ConsString::cast(this);
2130 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002131 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002132}
2133
2134
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002135String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002136 MaybeObject* flat = TryFlatten(pretenure);
2137 Object* successfully_flattened;
2138 if (flat->ToObject(&successfully_flattened)) {
2139 return String::cast(successfully_flattened);
2140 }
2141 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002142}
2143
2144
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002145uint16_t String::Get(int index) {
2146 ASSERT(index >= 0 && index < length());
2147 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002148 case kSeqStringTag | kAsciiStringTag:
2149 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2150 case kSeqStringTag | kTwoByteStringTag:
2151 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2152 case kConsStringTag | kAsciiStringTag:
2153 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002154 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002155 case kExternalStringTag | kAsciiStringTag:
2156 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2157 case kExternalStringTag | kTwoByteStringTag:
2158 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002159 default:
2160 break;
2161 }
2162
2163 UNREACHABLE();
2164 return 0;
2165}
2166
2167
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002168void String::Set(int index, uint16_t value) {
2169 ASSERT(index >= 0 && index < length());
2170 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002171
ager@chromium.org5ec48922009-05-05 07:25:34 +00002172 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002173 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2174 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002175}
2176
2177
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002178bool String::IsFlat() {
2179 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002180 case kConsStringTag: {
2181 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002182 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00002183 return second->length() == 0;
2184 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002185 default:
2186 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002187 }
2188}
2189
2190
ager@chromium.org7c537e22008-10-16 08:43:32 +00002191uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002192 ASSERT(index >= 0 && index < length());
2193 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2194}
2195
2196
ager@chromium.org7c537e22008-10-16 08:43:32 +00002197void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002198 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2199 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2200 static_cast<byte>(value));
2201}
2202
2203
ager@chromium.org7c537e22008-10-16 08:43:32 +00002204Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002205 return FIELD_ADDR(this, kHeaderSize);
2206}
2207
2208
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002209char* SeqAsciiString::GetChars() {
2210 return reinterpret_cast<char*>(GetCharsAddress());
2211}
2212
2213
ager@chromium.org7c537e22008-10-16 08:43:32 +00002214Address SeqTwoByteString::GetCharsAddress() {
2215 return FIELD_ADDR(this, kHeaderSize);
2216}
2217
2218
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002219uc16* SeqTwoByteString::GetChars() {
2220 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2221}
2222
2223
ager@chromium.org7c537e22008-10-16 08:43:32 +00002224uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002225 ASSERT(index >= 0 && index < length());
2226 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2227}
2228
2229
ager@chromium.org7c537e22008-10-16 08:43:32 +00002230void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002231 ASSERT(index >= 0 && index < length());
2232 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2233}
2234
2235
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002236int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002237 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002238}
2239
2240
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002241int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002242 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002243}
2244
2245
ager@chromium.org870a0b62008-11-04 11:43:05 +00002246String* ConsString::first() {
2247 return String::cast(READ_FIELD(this, kFirstOffset));
2248}
2249
2250
2251Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002252 return READ_FIELD(this, kFirstOffset);
2253}
2254
2255
ager@chromium.org870a0b62008-11-04 11:43:05 +00002256void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002257 WRITE_FIELD(this, kFirstOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002258 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002259}
2260
2261
ager@chromium.org870a0b62008-11-04 11:43:05 +00002262String* ConsString::second() {
2263 return String::cast(READ_FIELD(this, kSecondOffset));
2264}
2265
2266
2267Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002268 return READ_FIELD(this, kSecondOffset);
2269}
2270
2271
ager@chromium.org870a0b62008-11-04 11:43:05 +00002272void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002273 WRITE_FIELD(this, kSecondOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002274 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002275}
2276
2277
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002278ExternalAsciiString::Resource* ExternalAsciiString::resource() {
2279 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2280}
2281
2282
2283void ExternalAsciiString::set_resource(
2284 ExternalAsciiString::Resource* resource) {
2285 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2286}
2287
2288
2289ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
2290 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2291}
2292
2293
2294void ExternalTwoByteString::set_resource(
2295 ExternalTwoByteString::Resource* resource) {
2296 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2297}
2298
2299
ager@chromium.orgac091b72010-05-05 07:34:42 +00002300void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002301 set_finger_index(kEntriesIndex);
2302 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002303}
2304
2305
2306void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002307 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002308 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002309 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002310 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002311 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002312 MakeZeroSize();
2313}
2314
2315
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002316int JSFunctionResultCache::size() {
2317 return Smi::cast(get(kCacheSizeIndex))->value();
2318}
2319
2320
2321void JSFunctionResultCache::set_size(int size) {
2322 set(kCacheSizeIndex, Smi::FromInt(size));
2323}
2324
2325
2326int JSFunctionResultCache::finger_index() {
2327 return Smi::cast(get(kFingerIndex))->value();
2328}
2329
2330
2331void JSFunctionResultCache::set_finger_index(int finger_index) {
2332 set(kFingerIndex, Smi::FromInt(finger_index));
2333}
2334
2335
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002336byte ByteArray::get(int index) {
2337 ASSERT(index >= 0 && index < this->length());
2338 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2339}
2340
2341
2342void ByteArray::set(int index, byte value) {
2343 ASSERT(index >= 0 && index < this->length());
2344 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2345}
2346
2347
2348int ByteArray::get_int(int index) {
2349 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2350 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2351}
2352
2353
2354ByteArray* ByteArray::FromDataStartAddress(Address address) {
2355 ASSERT_TAG_ALIGNED(address);
2356 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2357}
2358
2359
2360Address ByteArray::GetDataStartAddress() {
2361 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2362}
2363
2364
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002365uint8_t* ExternalPixelArray::external_pixel_pointer() {
2366 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002367}
2368
2369
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002370uint8_t ExternalPixelArray::get(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002371 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002372 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002373 return ptr[index];
2374}
2375
2376
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002377void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002378 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002379 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002380 ptr[index] = value;
2381}
2382
2383
ager@chromium.org3811b432009-10-28 14:53:37 +00002384void* ExternalArray::external_pointer() {
2385 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2386 return reinterpret_cast<void*>(ptr);
2387}
2388
2389
2390void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2391 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2392 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2393}
2394
2395
2396int8_t ExternalByteArray::get(int index) {
2397 ASSERT((index >= 0) && (index < this->length()));
2398 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2399 return ptr[index];
2400}
2401
2402
2403void ExternalByteArray::set(int index, int8_t value) {
2404 ASSERT((index >= 0) && (index < this->length()));
2405 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2406 ptr[index] = value;
2407}
2408
2409
2410uint8_t ExternalUnsignedByteArray::get(int index) {
2411 ASSERT((index >= 0) && (index < this->length()));
2412 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2413 return ptr[index];
2414}
2415
2416
2417void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2418 ASSERT((index >= 0) && (index < this->length()));
2419 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2420 ptr[index] = value;
2421}
2422
2423
2424int16_t ExternalShortArray::get(int index) {
2425 ASSERT((index >= 0) && (index < this->length()));
2426 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2427 return ptr[index];
2428}
2429
2430
2431void ExternalShortArray::set(int index, int16_t value) {
2432 ASSERT((index >= 0) && (index < this->length()));
2433 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2434 ptr[index] = value;
2435}
2436
2437
2438uint16_t ExternalUnsignedShortArray::get(int index) {
2439 ASSERT((index >= 0) && (index < this->length()));
2440 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2441 return ptr[index];
2442}
2443
2444
2445void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2446 ASSERT((index >= 0) && (index < this->length()));
2447 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2448 ptr[index] = value;
2449}
2450
2451
2452int32_t ExternalIntArray::get(int index) {
2453 ASSERT((index >= 0) && (index < this->length()));
2454 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2455 return ptr[index];
2456}
2457
2458
2459void ExternalIntArray::set(int index, int32_t value) {
2460 ASSERT((index >= 0) && (index < this->length()));
2461 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2462 ptr[index] = value;
2463}
2464
2465
2466uint32_t ExternalUnsignedIntArray::get(int index) {
2467 ASSERT((index >= 0) && (index < this->length()));
2468 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2469 return ptr[index];
2470}
2471
2472
2473void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2474 ASSERT((index >= 0) && (index < this->length()));
2475 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2476 ptr[index] = value;
2477}
2478
2479
2480float ExternalFloatArray::get(int index) {
2481 ASSERT((index >= 0) && (index < this->length()));
2482 float* ptr = static_cast<float*>(external_pointer());
2483 return ptr[index];
2484}
2485
2486
2487void ExternalFloatArray::set(int index, float value) {
2488 ASSERT((index >= 0) && (index < this->length()));
2489 float* ptr = static_cast<float*>(external_pointer());
2490 ptr[index] = value;
2491}
2492
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002493
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002494double ExternalDoubleArray::get(int index) {
2495 ASSERT((index >= 0) && (index < this->length()));
2496 double* ptr = static_cast<double*>(external_pointer());
2497 return ptr[index];
2498}
2499
2500
2501void ExternalDoubleArray::set(int index, double value) {
2502 ASSERT((index >= 0) && (index < this->length()));
2503 double* ptr = static_cast<double*>(external_pointer());
2504 ptr[index] = value;
2505}
2506
2507
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002508int Map::visitor_id() {
2509 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2510}
2511
2512
2513void Map::set_visitor_id(int id) {
2514 ASSERT(0 <= id && id < 256);
2515 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2516}
2517
ager@chromium.org3811b432009-10-28 14:53:37 +00002518
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002519int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002520 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2521}
2522
2523
2524int Map::inobject_properties() {
2525 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002526}
2527
2528
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002529int Map::pre_allocated_property_fields() {
2530 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2531}
2532
2533
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002534int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002535 int instance_size = map->instance_size();
2536 if (instance_size != kVariableSizeSentinel) return instance_size;
2537 // We can ignore the "symbol" bit becase it is only set for symbols
2538 // and implies a string type.
2539 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002540 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002541 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002542 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002543 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002544 if (instance_type == ASCII_STRING_TYPE) {
2545 return SeqAsciiString::SizeFor(
2546 reinterpret_cast<SeqAsciiString*>(this)->length());
2547 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002548 if (instance_type == BYTE_ARRAY_TYPE) {
2549 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2550 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002551 if (instance_type == STRING_TYPE) {
2552 return SeqTwoByteString::SizeFor(
2553 reinterpret_cast<SeqTwoByteString*>(this)->length());
2554 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002555 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2556 return FixedDoubleArray::SizeFor(
2557 reinterpret_cast<FixedDoubleArray*>(this)->length());
2558 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002559 ASSERT(instance_type == CODE_TYPE);
2560 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002561}
2562
2563
2564void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002565 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002566 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002567 ASSERT(0 <= value && value < 256);
2568 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2569}
2570
2571
ager@chromium.org7c537e22008-10-16 08:43:32 +00002572void Map::set_inobject_properties(int value) {
2573 ASSERT(0 <= value && value < 256);
2574 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2575}
2576
2577
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002578void Map::set_pre_allocated_property_fields(int value) {
2579 ASSERT(0 <= value && value < 256);
2580 WRITE_BYTE_FIELD(this,
2581 kPreAllocatedPropertyFieldsOffset,
2582 static_cast<byte>(value));
2583}
2584
2585
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002586InstanceType Map::instance_type() {
2587 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2588}
2589
2590
2591void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002592 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2593}
2594
2595
2596int Map::unused_property_fields() {
2597 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2598}
2599
2600
2601void Map::set_unused_property_fields(int value) {
2602 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2603}
2604
2605
2606byte Map::bit_field() {
2607 return READ_BYTE_FIELD(this, kBitFieldOffset);
2608}
2609
2610
2611void Map::set_bit_field(byte value) {
2612 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2613}
2614
2615
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002616byte Map::bit_field2() {
2617 return READ_BYTE_FIELD(this, kBitField2Offset);
2618}
2619
2620
2621void Map::set_bit_field2(byte value) {
2622 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2623}
2624
2625
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002626void Map::set_non_instance_prototype(bool value) {
2627 if (value) {
2628 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2629 } else {
2630 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2631 }
2632}
2633
2634
2635bool Map::has_non_instance_prototype() {
2636 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2637}
2638
2639
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002640void Map::set_function_with_prototype(bool value) {
2641 if (value) {
2642 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2643 } else {
2644 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2645 }
2646}
2647
2648
2649bool Map::function_with_prototype() {
2650 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2651}
2652
2653
ager@chromium.org870a0b62008-11-04 11:43:05 +00002654void Map::set_is_access_check_needed(bool access_check_needed) {
2655 if (access_check_needed) {
2656 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2657 } else {
2658 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2659 }
2660}
2661
2662
2663bool Map::is_access_check_needed() {
2664 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2665}
2666
2667
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002668void Map::set_is_extensible(bool value) {
2669 if (value) {
2670 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2671 } else {
2672 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2673 }
2674}
2675
2676bool Map::is_extensible() {
2677 return ((1 << kIsExtensible) & bit_field2()) != 0;
2678}
2679
2680
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002681void Map::set_attached_to_shared_function_info(bool value) {
2682 if (value) {
2683 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2684 } else {
2685 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2686 }
2687}
2688
2689bool Map::attached_to_shared_function_info() {
2690 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2691}
2692
2693
2694void Map::set_is_shared(bool value) {
2695 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002696 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002697 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002698 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002699 }
2700}
2701
2702bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002703 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002704}
2705
2706
2707JSFunction* Map::unchecked_constructor() {
2708 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2709}
2710
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002711
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002712FixedArray* Map::unchecked_prototype_transitions() {
2713 return reinterpret_cast<FixedArray*>(
2714 READ_FIELD(this, kPrototypeTransitionsOffset));
2715}
2716
2717
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002718Code::Flags Code::flags() {
2719 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2720}
2721
2722
2723void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002724 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002725 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002726 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2727 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002728 ExtractArgumentsCountFromFlags(flags) >= 0);
2729 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2730}
2731
2732
2733Code::Kind Code::kind() {
2734 return ExtractKindFromFlags(flags());
2735}
2736
2737
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002738InLoopFlag Code::ic_in_loop() {
2739 return ExtractICInLoopFromFlags(flags());
2740}
2741
2742
kasper.lund7276f142008-07-30 08:49:36 +00002743InlineCacheState Code::ic_state() {
2744 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002745 // Only allow uninitialized or debugger states for non-IC code
2746 // objects. This is used in the debugger to determine whether or not
2747 // a call to code object has been replaced with a debug break call.
2748 ASSERT(is_inline_cache_stub() ||
2749 result == UNINITIALIZED ||
2750 result == DEBUG_BREAK ||
2751 result == DEBUG_PREPARE_STEP_IN);
2752 return result;
2753}
2754
2755
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002756Code::ExtraICState Code::extra_ic_state() {
2757 ASSERT(is_inline_cache_stub());
2758 return ExtractExtraICStateFromFlags(flags());
2759}
2760
2761
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002762PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002763 return ExtractTypeFromFlags(flags());
2764}
2765
2766
2767int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002768 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002769 return ExtractArgumentsCountFromFlags(flags());
2770}
2771
2772
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002773int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002774 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002775 kind() == UNARY_OP_IC ||
2776 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002777 kind() == COMPARE_IC ||
2778 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002779 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002780}
2781
2782
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002783void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002784 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002785 kind() == UNARY_OP_IC ||
2786 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002787 kind() == COMPARE_IC ||
2788 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002789 ASSERT(0 <= major && major < 256);
2790 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002791}
2792
2793
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002794bool Code::optimizable() {
2795 ASSERT(kind() == FUNCTION);
2796 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2797}
2798
2799
2800void Code::set_optimizable(bool value) {
2801 ASSERT(kind() == FUNCTION);
2802 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2803}
2804
2805
2806bool Code::has_deoptimization_support() {
2807 ASSERT(kind() == FUNCTION);
2808 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2809}
2810
2811
2812void Code::set_has_deoptimization_support(bool value) {
2813 ASSERT(kind() == FUNCTION);
2814 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2815}
2816
2817
2818int Code::allow_osr_at_loop_nesting_level() {
2819 ASSERT(kind() == FUNCTION);
2820 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2821}
2822
2823
2824void Code::set_allow_osr_at_loop_nesting_level(int level) {
2825 ASSERT(kind() == FUNCTION);
2826 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2827 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2828}
2829
2830
2831unsigned Code::stack_slots() {
2832 ASSERT(kind() == OPTIMIZED_FUNCTION);
2833 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2834}
2835
2836
2837void Code::set_stack_slots(unsigned slots) {
2838 ASSERT(kind() == OPTIMIZED_FUNCTION);
2839 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2840}
2841
2842
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002843unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002844 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002845 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002846}
2847
2848
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002849void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002850 ASSERT(kind() == OPTIMIZED_FUNCTION);
2851 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002852 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002853}
2854
2855
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002856unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002857 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002858 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002859}
2860
2861
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002862void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002863 ASSERT(kind() == FUNCTION);
2864 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002865 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002866}
2867
2868
2869CheckType Code::check_type() {
2870 ASSERT(is_call_stub() || is_keyed_call_stub());
2871 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2872 return static_cast<CheckType>(type);
2873}
2874
2875
2876void Code::set_check_type(CheckType value) {
2877 ASSERT(is_call_stub() || is_keyed_call_stub());
2878 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2879}
2880
2881
danno@chromium.org40cb8782011-05-25 07:58:50 +00002882byte Code::unary_op_type() {
2883 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002884 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
2885}
2886
2887
danno@chromium.org40cb8782011-05-25 07:58:50 +00002888void Code::set_unary_op_type(byte value) {
2889 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002890 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
2891}
2892
2893
danno@chromium.org40cb8782011-05-25 07:58:50 +00002894byte Code::binary_op_type() {
2895 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002896 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2897}
2898
2899
danno@chromium.org40cb8782011-05-25 07:58:50 +00002900void Code::set_binary_op_type(byte value) {
2901 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002902 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2903}
2904
2905
danno@chromium.org40cb8782011-05-25 07:58:50 +00002906byte Code::binary_op_result_type() {
2907 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002908 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2909}
2910
2911
danno@chromium.org40cb8782011-05-25 07:58:50 +00002912void Code::set_binary_op_result_type(byte value) {
2913 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002914 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2915}
2916
2917
2918byte Code::compare_state() {
2919 ASSERT(is_compare_ic_stub());
2920 return READ_BYTE_FIELD(this, kCompareStateOffset);
2921}
2922
2923
2924void Code::set_compare_state(byte value) {
2925 ASSERT(is_compare_ic_stub());
2926 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2927}
2928
2929
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002930byte Code::to_boolean_state() {
2931 ASSERT(is_to_boolean_ic_stub());
2932 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
2933}
2934
2935
2936void Code::set_to_boolean_state(byte value) {
2937 ASSERT(is_to_boolean_ic_stub());
2938 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
2939}
2940
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002941bool Code::is_inline_cache_stub() {
2942 Kind kind = this->kind();
2943 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2944}
2945
2946
2947Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002948 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002949 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002950 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002951 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002952 int argc,
2953 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002954 // Extra IC state is only allowed for call IC stubs or for store IC
2955 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002956 ASSERT(extra_ic_state == kNoExtraICState ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002957 (kind == CALL_IC) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00002958 (kind == STORE_IC) ||
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002959 (kind == KEYED_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002960 // Compute the bit mask.
2961 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002962 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002963 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002964 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002965 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002966 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002967 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002968 // Cast to flags and validate result before returning it.
2969 Flags result = static_cast<Flags>(bits);
2970 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002971 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002972 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002973 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002974 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002975 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2976 return result;
2977}
2978
2979
2980Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2981 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002982 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002983 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002984 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002985 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002986 return ComputeFlags(
2987 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002988}
2989
2990
2991Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2992 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2993 return static_cast<Kind>(bits);
2994}
2995
2996
kasper.lund7276f142008-07-30 08:49:36 +00002997InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2998 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002999 return static_cast<InlineCacheState>(bits);
3000}
3001
3002
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003003Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
3004 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
3005 return static_cast<ExtraICState>(bits);
3006}
3007
3008
kasperl@chromium.org71affb52009-05-26 05:44:31 +00003009InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
3010 int bits = (flags & kFlagsICInLoopMask);
3011 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
3012}
3013
3014
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003015PropertyType Code::ExtractTypeFromFlags(Flags flags) {
3016 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
3017 return static_cast<PropertyType>(bits);
3018}
3019
3020
3021int Code::ExtractArgumentsCountFromFlags(Flags flags) {
3022 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
3023}
3024
3025
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003026InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
3027 int bits = (flags & kFlagsCacheInPrototypeMapMask);
3028 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
3029}
3030
3031
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003032Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
3033 int bits = flags & ~kFlagsTypeMask;
3034 return static_cast<Flags>(bits);
3035}
3036
3037
ager@chromium.org8bb60582008-12-11 12:02:20 +00003038Code* Code::GetCodeFromTargetAddress(Address address) {
3039 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3040 // GetCodeFromTargetAddress might be called when marking objects during mark
3041 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3042 // Code::cast. Code::cast does not work when the object's map is
3043 // marked.
3044 Code* result = reinterpret_cast<Code*>(code);
3045 return result;
3046}
3047
3048
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003049Isolate* Map::isolate() {
3050 return heap()->isolate();
3051}
3052
3053
3054Heap* Map::heap() {
3055 // NOTE: address() helper is not used to save one instruction.
3056 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3057 ASSERT(heap != NULL);
3058 ASSERT(heap->isolate() == Isolate::Current());
3059 return heap;
3060}
3061
3062
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003063Heap* Code::heap() {
3064 // NOTE: address() helper is not used to save one instruction.
3065 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3066 ASSERT(heap != NULL);
3067 ASSERT(heap->isolate() == Isolate::Current());
3068 return heap;
3069}
3070
3071
3072Isolate* Code::isolate() {
3073 return heap()->isolate();
3074}
3075
3076
3077Heap* JSGlobalPropertyCell::heap() {
3078 // NOTE: address() helper is not used to save one instruction.
3079 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3080 ASSERT(heap != NULL);
3081 ASSERT(heap->isolate() == Isolate::Current());
3082 return heap;
3083}
3084
3085
3086Isolate* JSGlobalPropertyCell::isolate() {
3087 return heap()->isolate();
3088}
3089
3090
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003091Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3092 return HeapObject::
3093 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3094}
3095
3096
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003097Object* Map::prototype() {
3098 return READ_FIELD(this, kPrototypeOffset);
3099}
3100
3101
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003102void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003103 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003104 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003105 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003106}
3107
3108
lrn@chromium.org303ada72010-10-27 09:33:13 +00003109MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003110 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003111 Object* obj;
3112 { MaybeObject* maybe_obj = CopyDropTransitions();
3113 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3114 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003115 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003116 new_map->set_elements_kind(JSObject::FAST_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003117 isolate()->counters()->map_to_fast_elements()->Increment();
3118 return new_map;
3119}
3120
3121
3122MaybeObject* Map::GetFastDoubleElementsMap() {
3123 if (has_fast_double_elements()) return this;
3124 Object* obj;
3125 { MaybeObject* maybe_obj = CopyDropTransitions();
3126 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3127 }
3128 Map* new_map = Map::cast(obj);
3129 new_map->set_elements_kind(JSObject::FAST_DOUBLE_ELEMENTS);
3130 isolate()->counters()->map_to_fast_double_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003131 return new_map;
3132}
3133
3134
lrn@chromium.org303ada72010-10-27 09:33:13 +00003135MaybeObject* Map::GetSlowElementsMap() {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003136 if (!has_fast_elements() && !has_fast_double_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003137 Object* obj;
3138 { MaybeObject* maybe_obj = CopyDropTransitions();
3139 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3140 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003141 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003142 new_map->set_elements_kind(JSObject::DICTIONARY_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003143 isolate()->counters()->map_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003144 return new_map;
3145}
3146
3147
danno@chromium.org40cb8782011-05-25 07:58:50 +00003148DescriptorArray* Map::instance_descriptors() {
3149 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3150 if (object->IsSmi()) {
3151 return HEAP->empty_descriptor_array();
3152 } else {
3153 return DescriptorArray::cast(object);
3154 }
3155}
3156
3157
3158void Map::init_instance_descriptors() {
3159 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3160}
3161
3162
3163void Map::clear_instance_descriptors() {
3164 Object* object = READ_FIELD(this,
3165 kInstanceDescriptorsOrBitField3Offset);
3166 if (!object->IsSmi()) {
3167 WRITE_FIELD(
3168 this,
3169 kInstanceDescriptorsOrBitField3Offset,
3170 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3171 }
3172}
3173
3174
3175void Map::set_instance_descriptors(DescriptorArray* value,
3176 WriteBarrierMode mode) {
3177 Object* object = READ_FIELD(this,
3178 kInstanceDescriptorsOrBitField3Offset);
3179 if (value == isolate()->heap()->empty_descriptor_array()) {
3180 clear_instance_descriptors();
3181 return;
3182 } else {
3183 if (object->IsSmi()) {
3184 value->set_bit_field3_storage(Smi::cast(object)->value());
3185 } else {
3186 value->set_bit_field3_storage(
3187 DescriptorArray::cast(object)->bit_field3_storage());
3188 }
3189 }
3190 ASSERT(!is_shared());
3191 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
3192 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3193 this,
3194 kInstanceDescriptorsOrBitField3Offset,
3195 mode);
3196}
3197
3198
3199int Map::bit_field3() {
3200 Object* object = READ_FIELD(this,
3201 kInstanceDescriptorsOrBitField3Offset);
3202 if (object->IsSmi()) {
3203 return Smi::cast(object)->value();
3204 } else {
3205 return DescriptorArray::cast(object)->bit_field3_storage();
3206 }
3207}
3208
3209
3210void Map::set_bit_field3(int value) {
3211 ASSERT(Smi::IsValid(value));
3212 Object* object = READ_FIELD(this,
3213 kInstanceDescriptorsOrBitField3Offset);
3214 if (object->IsSmi()) {
3215 WRITE_FIELD(this,
3216 kInstanceDescriptorsOrBitField3Offset,
3217 Smi::FromInt(value));
3218 } else {
3219 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3220 }
3221}
3222
3223
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003224ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003225ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003226ACCESSORS(Map, constructor, Object, kConstructorOffset)
3227
3228ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
3229ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003230ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
3231 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003232
3233ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3234ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003235ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003236
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003237ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003238
3239ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3240ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3241ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3242ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3243ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3244
3245ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3246ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3247ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3248
3249ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3250ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3251ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3252ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3253ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3254ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3255
3256ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3257ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3258
3259ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3260ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3261
3262ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3263ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003264ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3265 kPropertyAccessorsOffset)
3266ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3267 kPrototypeTemplateOffset)
3268ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3269ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3270 kNamedPropertyHandlerOffset)
3271ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3272 kIndexedPropertyHandlerOffset)
3273ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3274 kInstanceTemplateOffset)
3275ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3276ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003277ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3278 kInstanceCallHandlerOffset)
3279ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3280 kAccessCheckInfoOffset)
3281ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3282
3283ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003284ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3285 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003286
3287ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3288ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3289
3290ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3291
3292ACCESSORS(Script, source, Object, kSourceOffset)
3293ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003294ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003295ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3296ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003297ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003298ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003299ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003300ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003301ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003302ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003303ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003304ACCESSORS(Script, eval_from_instructions_offset, Smi,
3305 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003306
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003307#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003308ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3309ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3310ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3311ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3312
3313ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3314ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3315ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3316ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003317#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003318
3319ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003320ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3321ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003322ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3323 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003324ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003325ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3326ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003327ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003328ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3329 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003330
3331BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3332 kHiddenPrototypeBit)
3333BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3334BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3335 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003336BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3337 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003338BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3339 kIsExpressionBit)
3340BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3341 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003342BOOL_GETTER(SharedFunctionInfo,
3343 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003344 has_only_simple_this_property_assignments,
3345 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003346BOOL_ACCESSORS(SharedFunctionInfo,
3347 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003348 allows_lazy_compilation,
3349 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003350BOOL_ACCESSORS(SharedFunctionInfo,
3351 compiler_hints,
3352 uses_arguments,
3353 kUsesArguments)
3354BOOL_ACCESSORS(SharedFunctionInfo,
3355 compiler_hints,
3356 has_duplicate_parameters,
3357 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003358
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003359
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003360#if V8_HOST_ARCH_32_BIT
3361SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3362SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003363 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003364SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003365 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003366SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3367SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003368 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003369SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3370SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003371 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003372SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003373 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003374SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003375 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003376SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003377#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003378
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003379#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003380 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003381 int holder::name() { \
3382 int value = READ_INT_FIELD(this, offset); \
3383 ASSERT(kHeapObjectTag == 1); \
3384 ASSERT((value & kHeapObjectTag) == 0); \
3385 return value >> 1; \
3386 } \
3387 void holder::set_##name(int value) { \
3388 ASSERT(kHeapObjectTag == 1); \
3389 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3390 (value & 0xC0000000) == 0x000000000); \
3391 WRITE_INT_FIELD(this, \
3392 offset, \
3393 (value << 1) & ~kHeapObjectTag); \
3394 }
3395
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003396#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3397 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003398 INT_ACCESSORS(holder, name, offset)
3399
3400
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003401PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003402PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3403 formal_parameter_count,
3404 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003405
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003406PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3407 expected_nof_properties,
3408 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003409PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3410
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003411PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3412PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3413 start_position_and_type,
3414 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003415
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003416PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3417 function_token_position,
3418 kFunctionTokenPositionOffset)
3419PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3420 compiler_hints,
3421 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003422
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003423PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3424 this_property_assignments_count,
3425 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003426PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003427#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003428
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003429
3430int SharedFunctionInfo::construction_count() {
3431 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3432}
3433
3434
3435void SharedFunctionInfo::set_construction_count(int value) {
3436 ASSERT(0 <= value && value < 256);
3437 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3438}
3439
3440
whesse@chromium.org7b260152011-06-20 15:33:18 +00003441BOOL_ACCESSORS(SharedFunctionInfo,
3442 compiler_hints,
3443 live_objects_may_exist,
3444 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003445
3446
3447bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003448 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003449}
3450
3451
whesse@chromium.org7b260152011-06-20 15:33:18 +00003452BOOL_GETTER(SharedFunctionInfo,
3453 compiler_hints,
3454 optimization_disabled,
3455 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003456
3457
3458void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3459 set_compiler_hints(BooleanBit::set(compiler_hints(),
3460 kOptimizationDisabled,
3461 disable));
3462 // If disabling optimizations we reflect that in the code object so
3463 // it will not be counted as optimizable code.
3464 if ((code()->kind() == Code::FUNCTION) && disable) {
3465 code()->set_optimizable(false);
3466 }
3467}
3468
3469
whesse@chromium.org7b260152011-06-20 15:33:18 +00003470BOOL_ACCESSORS(SharedFunctionInfo,
3471 compiler_hints,
3472 strict_mode,
3473 kStrictModeFunction)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003474
3475
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003476bool SharedFunctionInfo::native() {
3477 return BooleanBit::get(compiler_hints(), kNative);
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003478}
3479
3480
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003481void SharedFunctionInfo::set_native(bool value) {
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003482 set_compiler_hints(BooleanBit::set(compiler_hints(),
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003483 kNative,
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003484 value));
3485}
3486
3487
whesse@chromium.org7b260152011-06-20 15:33:18 +00003488bool SharedFunctionInfo::bound() {
3489 return BooleanBit::get(compiler_hints(), kBoundFunction);
3490}
3491
3492
3493void SharedFunctionInfo::set_bound(bool value) {
3494 set_compiler_hints(BooleanBit::set(compiler_hints(),
3495 kBoundFunction,
3496 value));
3497}
3498
3499
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003500ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3501ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3502
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003503ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3504
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003505bool Script::HasValidSource() {
3506 Object* src = this->source();
3507 if (!src->IsString()) return true;
3508 String* src_str = String::cast(src);
3509 if (!StringShape(src_str).IsExternal()) return true;
3510 if (src_str->IsAsciiRepresentation()) {
3511 return ExternalAsciiString::cast(src)->resource() != NULL;
3512 } else if (src_str->IsTwoByteRepresentation()) {
3513 return ExternalTwoByteString::cast(src)->resource() != NULL;
3514 }
3515 return true;
3516}
3517
3518
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003519void SharedFunctionInfo::DontAdaptArguments() {
3520 ASSERT(code()->kind() == Code::BUILTIN);
3521 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3522}
3523
3524
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003525int SharedFunctionInfo::start_position() {
3526 return start_position_and_type() >> kStartPositionShift;
3527}
3528
3529
3530void SharedFunctionInfo::set_start_position(int start_position) {
3531 set_start_position_and_type((start_position << kStartPositionShift)
3532 | (start_position_and_type() & ~kStartPositionMask));
3533}
3534
3535
3536Code* SharedFunctionInfo::code() {
3537 return Code::cast(READ_FIELD(this, kCodeOffset));
3538}
3539
3540
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003541Code* SharedFunctionInfo::unchecked_code() {
3542 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3543}
3544
3545
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003546void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003547 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003548 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003549}
3550
3551
ager@chromium.orgb5737492010-07-15 09:29:43 +00003552SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3553 return reinterpret_cast<SerializedScopeInfo*>(
3554 READ_FIELD(this, kScopeInfoOffset));
3555}
3556
3557
3558void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3559 WriteBarrierMode mode) {
3560 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003561 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003562}
3563
3564
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003565Smi* SharedFunctionInfo::deopt_counter() {
3566 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3567}
3568
3569
3570void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3571 WRITE_FIELD(this, kDeoptCounterOffset, value);
3572}
3573
3574
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003575bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003576 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003577 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003578}
3579
3580
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003581bool SharedFunctionInfo::IsApiFunction() {
3582 return function_data()->IsFunctionTemplateInfo();
3583}
3584
3585
3586FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3587 ASSERT(IsApiFunction());
3588 return FunctionTemplateInfo::cast(function_data());
3589}
3590
3591
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003592bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003593 return function_data()->IsSmi();
3594}
3595
3596
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003597BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3598 ASSERT(HasBuiltinFunctionId());
3599 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003600}
3601
3602
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003603int SharedFunctionInfo::code_age() {
3604 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3605}
3606
3607
3608void SharedFunctionInfo::set_code_age(int code_age) {
3609 set_compiler_hints(compiler_hints() |
3610 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3611}
3612
3613
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003614bool SharedFunctionInfo::has_deoptimization_support() {
3615 Code* code = this->code();
3616 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3617}
3618
3619
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003620bool JSFunction::IsBuiltin() {
3621 return context()->global()->IsJSBuiltinsObject();
3622}
3623
3624
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003625bool JSFunction::NeedsArgumentsAdaption() {
3626 return shared()->formal_parameter_count() !=
3627 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3628}
3629
3630
3631bool JSFunction::IsOptimized() {
3632 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3633}
3634
3635
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003636bool JSFunction::IsOptimizable() {
3637 return code()->kind() == Code::FUNCTION && code()->optimizable();
3638}
3639
3640
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003641bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003642 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003643}
3644
3645
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003646Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003647 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003648}
3649
3650
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003651Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003652 return reinterpret_cast<Code*>(
3653 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003654}
3655
3656
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003657void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003658 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003659 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003660 Address entry = value->entry();
3661 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003662}
3663
3664
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003665void JSFunction::ReplaceCode(Code* code) {
3666 bool was_optimized = IsOptimized();
3667 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3668
3669 set_code(code);
3670
3671 // Add/remove the function from the list of optimized functions for this
3672 // context based on the state change.
3673 if (!was_optimized && is_optimized) {
3674 context()->global_context()->AddOptimizedFunction(this);
3675 }
3676 if (was_optimized && !is_optimized) {
3677 context()->global_context()->RemoveOptimizedFunction(this);
3678 }
3679}
3680
3681
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003682Context* JSFunction::context() {
3683 return Context::cast(READ_FIELD(this, kContextOffset));
3684}
3685
3686
3687Object* JSFunction::unchecked_context() {
3688 return READ_FIELD(this, kContextOffset);
3689}
3690
3691
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003692SharedFunctionInfo* JSFunction::unchecked_shared() {
3693 return reinterpret_cast<SharedFunctionInfo*>(
3694 READ_FIELD(this, kSharedFunctionInfoOffset));
3695}
3696
3697
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003698void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003699 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003700 WRITE_FIELD(this, kContextOffset, value);
3701 WRITE_BARRIER(this, kContextOffset);
3702}
3703
3704ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3705 kPrototypeOrInitialMapOffset)
3706
3707
3708Map* JSFunction::initial_map() {
3709 return Map::cast(prototype_or_initial_map());
3710}
3711
3712
3713void JSFunction::set_initial_map(Map* value) {
3714 set_prototype_or_initial_map(value);
3715}
3716
3717
3718bool JSFunction::has_initial_map() {
3719 return prototype_or_initial_map()->IsMap();
3720}
3721
3722
3723bool JSFunction::has_instance_prototype() {
3724 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3725}
3726
3727
3728bool JSFunction::has_prototype() {
3729 return map()->has_non_instance_prototype() || has_instance_prototype();
3730}
3731
3732
3733Object* JSFunction::instance_prototype() {
3734 ASSERT(has_instance_prototype());
3735 if (has_initial_map()) return initial_map()->prototype();
3736 // When there is no initial map and the prototype is a JSObject, the
3737 // initial map field is used for the prototype field.
3738 return prototype_or_initial_map();
3739}
3740
3741
3742Object* JSFunction::prototype() {
3743 ASSERT(has_prototype());
3744 // If the function's prototype property has been set to a non-JSObject
3745 // value, that value is stored in the constructor field of the map.
3746 if (map()->has_non_instance_prototype()) return map()->constructor();
3747 return instance_prototype();
3748}
3749
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003750bool JSFunction::should_have_prototype() {
3751 return map()->function_with_prototype();
3752}
3753
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003754
3755bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003756 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003757}
3758
3759
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003760int JSFunction::NumberOfLiterals() {
3761 return literals()->length();
3762}
3763
3764
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003765Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003766 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003767 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003768}
3769
3770
3771void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3772 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003773 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003774 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3775 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3776}
3777
3778
3779Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003780 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003781 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3782}
3783
3784
3785void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3786 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003787 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003788 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003789 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003790}
3791
3792
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003793ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003794ACCESSORS(JSProxy, padding, Object, kPaddingOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003795
3796
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003797Address Foreign::address() {
3798 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003799}
3800
3801
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003802void Foreign::set_address(Address value) {
3803 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003804}
3805
3806
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003807ACCESSORS(JSValue, value, Object, kValueOffset)
3808
3809
3810JSValue* JSValue::cast(Object* obj) {
3811 ASSERT(obj->IsJSValue());
3812 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3813 return reinterpret_cast<JSValue*>(obj);
3814}
3815
3816
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003817ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3818ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3819ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3820ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3821ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3822SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3823SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3824
3825
3826JSMessageObject* JSMessageObject::cast(Object* obj) {
3827 ASSERT(obj->IsJSMessageObject());
3828 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3829 return reinterpret_cast<JSMessageObject*>(obj);
3830}
3831
3832
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003833INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003834ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003835ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003836ACCESSORS(Code, next_code_flushing_candidate,
3837 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003838
3839
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003840byte* Code::instruction_start() {
3841 return FIELD_ADDR(this, kHeaderSize);
3842}
3843
3844
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003845byte* Code::instruction_end() {
3846 return instruction_start() + instruction_size();
3847}
3848
3849
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003850int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003851 return RoundUp(instruction_size(), kObjectAlignment);
3852}
3853
3854
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003855FixedArray* Code::unchecked_deoptimization_data() {
3856 return reinterpret_cast<FixedArray*>(
3857 READ_FIELD(this, kDeoptimizationDataOffset));
3858}
3859
3860
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003861ByteArray* Code::unchecked_relocation_info() {
3862 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003863}
3864
3865
3866byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003867 return unchecked_relocation_info()->GetDataStartAddress();
3868}
3869
3870
3871int Code::relocation_size() {
3872 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003873}
3874
3875
3876byte* Code::entry() {
3877 return instruction_start();
3878}
3879
3880
3881bool Code::contains(byte* pc) {
3882 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003883 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003884}
3885
3886
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003887ACCESSORS(JSArray, length, Object, kLengthOffset)
3888
3889
ager@chromium.org236ad962008-09-25 09:45:57 +00003890ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003891
3892
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003893JSRegExp::Type JSRegExp::TypeTag() {
3894 Object* data = this->data();
3895 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3896 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3897 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003898}
3899
3900
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003901JSRegExp::Type JSRegExp::TypeTagUnchecked() {
3902 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
3903 return static_cast<JSRegExp::Type>(smi->value());
3904}
3905
3906
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003907int JSRegExp::CaptureCount() {
3908 switch (TypeTag()) {
3909 case ATOM:
3910 return 0;
3911 case IRREGEXP:
3912 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3913 default:
3914 UNREACHABLE();
3915 return -1;
3916 }
3917}
3918
3919
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003920JSRegExp::Flags JSRegExp::GetFlags() {
3921 ASSERT(this->data()->IsFixedArray());
3922 Object* data = this->data();
3923 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3924 return Flags(smi->value());
3925}
3926
3927
3928String* JSRegExp::Pattern() {
3929 ASSERT(this->data()->IsFixedArray());
3930 Object* data = this->data();
3931 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3932 return pattern;
3933}
3934
3935
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003936Object* JSRegExp::DataAt(int index) {
3937 ASSERT(TypeTag() != NOT_COMPILED);
3938 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003939}
3940
3941
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003942Object* JSRegExp::DataAtUnchecked(int index) {
3943 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
3944 int offset = FixedArray::kHeaderSize + index * kPointerSize;
3945 return READ_FIELD(fa, offset);
3946}
3947
3948
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003949void JSRegExp::SetDataAt(int index, Object* value) {
3950 ASSERT(TypeTag() != NOT_COMPILED);
3951 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3952 FixedArray::cast(data())->set(index, value);
3953}
3954
3955
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003956void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
3957 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3958 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
3959 if (value->IsSmi()) {
3960 fa->set_unchecked(index, Smi::cast(value));
3961 } else {
3962 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
3963 }
3964}
3965
3966
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003967JSObject::ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003968 ElementsKind kind = map()->elements_kind();
3969 ASSERT((kind == FAST_ELEMENTS &&
3970 (elements()->map() == GetHeap()->fixed_array_map() ||
3971 elements()->map() == GetHeap()->fixed_cow_array_map())) ||
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003972 (kind == FAST_DOUBLE_ELEMENTS &&
3973 elements()->IsFixedDoubleArray()) ||
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003974 (kind == DICTIONARY_ELEMENTS &&
3975 elements()->IsFixedArray() &&
3976 elements()->IsDictionary()) ||
3977 (kind > DICTIONARY_ELEMENTS));
3978 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003979}
3980
3981
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003982bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003983 return GetElementsKind() == FAST_ELEMENTS;
3984}
3985
3986
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003987bool JSObject::HasFastDoubleElements() {
3988 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
3989}
3990
3991
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003992bool JSObject::HasDictionaryElements() {
3993 return GetElementsKind() == DICTIONARY_ELEMENTS;
3994}
3995
3996
ager@chromium.org3811b432009-10-28 14:53:37 +00003997bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003998 HeapObject* array = elements();
3999 ASSERT(array != NULL);
4000 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004001}
4002
4003
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004004#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4005bool JSObject::HasExternal##name##Elements() { \
4006 HeapObject* array = elements(); \
4007 ASSERT(array != NULL); \
4008 if (!array->IsHeapObject()) \
4009 return false; \
4010 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004011}
4012
4013
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004014EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4015EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4016EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4017EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4018 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4019EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4020EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4021 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4022EXTERNAL_ELEMENTS_CHECK(Float,
4023 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004024EXTERNAL_ELEMENTS_CHECK(Double,
4025 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004026EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004027
4028
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004029bool JSObject::HasNamedInterceptor() {
4030 return map()->has_named_interceptor();
4031}
4032
4033
4034bool JSObject::HasIndexedInterceptor() {
4035 return map()->has_indexed_interceptor();
4036}
4037
4038
ager@chromium.org5c838252010-02-19 08:53:10 +00004039bool JSObject::AllowsSetElementsLength() {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004040 bool result = elements()->IsFixedArray() ||
4041 elements()->IsFixedDoubleArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004042 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00004043 return result;
4044}
4045
4046
lrn@chromium.org303ada72010-10-27 09:33:13 +00004047MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004048 ASSERT(HasFastElements());
4049 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004050 Isolate* isolate = GetIsolate();
4051 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004052 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004053 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4054 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004055 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4056 return maybe_writable_elems;
4057 }
4058 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004059 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004060 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004061 return writable_elems;
4062}
4063
4064
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004065StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004066 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004067 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004068}
4069
4070
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004071NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004072 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004073 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004074}
4075
4076
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004077bool String::IsHashFieldComputed(uint32_t field) {
4078 return (field & kHashNotComputedMask) == 0;
4079}
4080
4081
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004082bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004083 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004084}
4085
4086
4087uint32_t String::Hash() {
4088 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004089 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004090 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004091 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004092 return ComputeAndSetHash();
4093}
4094
4095
ager@chromium.org7c537e22008-10-16 08:43:32 +00004096StringHasher::StringHasher(int length)
4097 : length_(length),
4098 raw_running_hash_(0),
4099 array_index_(0),
4100 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4101 is_first_char_(true),
4102 is_valid_(true) { }
4103
4104
4105bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004106 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004107}
4108
4109
4110void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004111 // Use the Jenkins one-at-a-time hash function to update the hash
4112 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004113 raw_running_hash_ += c;
4114 raw_running_hash_ += (raw_running_hash_ << 10);
4115 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004116 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004117 if (is_array_index_) {
4118 if (c < '0' || c > '9') {
4119 is_array_index_ = false;
4120 } else {
4121 int d = c - '0';
4122 if (is_first_char_) {
4123 is_first_char_ = false;
4124 if (c == '0' && length_ > 1) {
4125 is_array_index_ = false;
4126 return;
4127 }
4128 }
4129 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4130 is_array_index_ = false;
4131 } else {
4132 array_index_ = array_index_ * 10 + d;
4133 }
4134 }
4135 }
4136}
4137
4138
4139void StringHasher::AddCharacterNoIndex(uc32 c) {
4140 ASSERT(!is_array_index());
4141 raw_running_hash_ += c;
4142 raw_running_hash_ += (raw_running_hash_ << 10);
4143 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4144}
4145
4146
4147uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004148 // Get the calculated raw hash value and do some more bit ops to distribute
4149 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004150 uint32_t result = raw_running_hash_;
4151 result += (result << 3);
4152 result ^= (result >> 11);
4153 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004154 if (result == 0) {
4155 result = 27;
4156 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004157 return result;
4158}
4159
4160
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004161template <typename schar>
4162uint32_t HashSequentialString(const schar* chars, int length) {
4163 StringHasher hasher(length);
4164 if (!hasher.has_trivial_hash()) {
4165 int i;
4166 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4167 hasher.AddCharacter(chars[i]);
4168 }
4169 for (; i < length; i++) {
4170 hasher.AddCharacterNoIndex(chars[i]);
4171 }
4172 }
4173 return hasher.GetHashField();
4174}
4175
4176
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004177bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004178 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004179 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4180 return false;
4181 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004182 return SlowAsArrayIndex(index);
4183}
4184
4185
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004186Object* JSReceiver::GetPrototype() {
4187 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004188}
4189
4190
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004191bool JSReceiver::HasProperty(String* name) {
4192 if (IsJSProxy()) {
4193 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4194 }
4195 return GetPropertyAttribute(name) != ABSENT;
4196}
4197
4198
4199bool JSReceiver::HasLocalProperty(String* name) {
4200 if (IsJSProxy()) {
4201 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4202 }
4203 return GetLocalPropertyAttribute(name) != ABSENT;
4204}
4205
4206
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004207PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004208 return GetPropertyAttributeWithReceiver(this, key);
4209}
4210
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004211// TODO(504): this may be useful in other places too where JSGlobalProxy
4212// is used.
4213Object* JSObject::BypassGlobalProxy() {
4214 if (IsJSGlobalProxy()) {
4215 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004216 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004217 ASSERT(proto->IsJSGlobalObject());
4218 return proto;
4219 }
4220 return this;
4221}
4222
4223
4224bool JSObject::HasHiddenPropertiesObject() {
4225 ASSERT(!IsJSGlobalProxy());
4226 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004227 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004228 false) != ABSENT;
4229}
4230
4231
4232Object* JSObject::GetHiddenPropertiesObject() {
4233 ASSERT(!IsJSGlobalProxy());
4234 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004235 // You can't install a getter on a property indexed by the hidden symbol,
4236 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
4237 // object.
4238 Object* result =
4239 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004240 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00004241 &attributes)->ToObjectUnchecked();
4242 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004243}
4244
4245
lrn@chromium.org303ada72010-10-27 09:33:13 +00004246MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004247 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004248 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004249 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00004250 DONT_ENUM,
4251 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004252}
4253
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004254
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004255bool JSObject::HasHiddenProperties() {
4256 return !GetHiddenProperties(OMIT_CREATION)->ToObjectChecked()->IsUndefined();
4257}
4258
4259
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004260bool JSObject::HasElement(uint32_t index) {
4261 return HasElementWithReceiver(this, index);
4262}
4263
4264
4265bool AccessorInfo::all_can_read() {
4266 return BooleanBit::get(flag(), kAllCanReadBit);
4267}
4268
4269
4270void AccessorInfo::set_all_can_read(bool value) {
4271 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4272}
4273
4274
4275bool AccessorInfo::all_can_write() {
4276 return BooleanBit::get(flag(), kAllCanWriteBit);
4277}
4278
4279
4280void AccessorInfo::set_all_can_write(bool value) {
4281 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4282}
4283
4284
ager@chromium.org870a0b62008-11-04 11:43:05 +00004285bool AccessorInfo::prohibits_overwriting() {
4286 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4287}
4288
4289
4290void AccessorInfo::set_prohibits_overwriting(bool value) {
4291 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4292}
4293
4294
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004295PropertyAttributes AccessorInfo::property_attributes() {
4296 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4297}
4298
4299
4300void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
4301 ASSERT(AttributesField::is_valid(attributes));
4302 int rest_value = flag()->value() & ~AttributesField::mask();
4303 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
4304}
4305
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004306
4307template<typename Shape, typename Key>
4308void Dictionary<Shape, Key>::SetEntry(int entry,
4309 Object* key,
4310 Object* value) {
4311 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4312}
4313
4314
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004315template<typename Shape, typename Key>
4316void Dictionary<Shape, Key>::SetEntry(int entry,
4317 Object* key,
4318 Object* value,
4319 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004320 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004321 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004322 AssertNoAllocation no_gc;
4323 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004324 FixedArray::set(index, key, mode);
4325 FixedArray::set(index+1, value, mode);
4326 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004327}
4328
4329
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004330bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4331 ASSERT(other->IsNumber());
4332 return key == static_cast<uint32_t>(other->Number());
4333}
4334
4335
4336uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4337 return ComputeIntegerHash(key);
4338}
4339
4340
4341uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4342 ASSERT(other->IsNumber());
4343 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4344}
4345
4346
4347MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4348 return Isolate::Current()->heap()->NumberFromUint32(key);
4349}
4350
4351
4352bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4353 // We know that all entries in a hash table had their hash keys created.
4354 // Use that knowledge to have fast failure.
4355 if (key->Hash() != String::cast(other)->Hash()) return false;
4356 return key->Equals(String::cast(other));
4357}
4358
4359
4360uint32_t StringDictionaryShape::Hash(String* key) {
4361 return key->Hash();
4362}
4363
4364
4365uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4366 return String::cast(other)->Hash();
4367}
4368
4369
4370MaybeObject* StringDictionaryShape::AsObject(String* key) {
4371 return key;
4372}
4373
4374
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004375bool ObjectHashTableShape::IsMatch(JSObject* key, Object* other) {
4376 return key == JSObject::cast(other);
4377}
4378
4379
4380uint32_t ObjectHashTableShape::Hash(JSObject* key) {
4381 MaybeObject* maybe_hash = key->GetIdentityHash(JSObject::OMIT_CREATION);
4382 ASSERT(!maybe_hash->IsFailure());
4383 return Smi::cast(maybe_hash->ToObjectUnchecked())->value();
4384}
4385
4386
4387uint32_t ObjectHashTableShape::HashForObject(JSObject* key, Object* other) {
4388 MaybeObject* maybe_hash = JSObject::cast(other)->GetIdentityHash(
4389 JSObject::OMIT_CREATION);
4390 ASSERT(!maybe_hash->IsFailure());
4391 return Smi::cast(maybe_hash->ToObjectUnchecked())->value();
4392}
4393
4394
4395MaybeObject* ObjectHashTableShape::AsObject(JSObject* key) {
4396 return key;
4397}
4398
4399
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004400void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004401 // No write barrier is needed since empty_fixed_array is not in new space.
4402 // Please note this function is used during marking:
4403 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004404 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4405 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004406}
4407
4408
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004409void JSArray::EnsureSize(int required_size) {
4410 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004411 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004412 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4413 if (elts->length() < required_size) {
4414 // Doubling in size would be overkill, but leave some slack to avoid
4415 // constantly growing.
4416 Expand(required_size + (required_size >> 3));
4417 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004418 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004419 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4420 // Expand will allocate a new backing store in new space even if the size
4421 // we asked for isn't larger than what we had before.
4422 Expand(required_size);
4423 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004424}
4425
4426
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004427void JSArray::set_length(Smi* length) {
4428 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4429}
4430
4431
ager@chromium.org7c537e22008-10-16 08:43:32 +00004432void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004433 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004434 set_elements(storage);
4435}
4436
4437
lrn@chromium.org303ada72010-10-27 09:33:13 +00004438MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004439 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004440 return GetHeap()->CopyFixedArray(this);
4441}
4442
4443
4444Relocatable::Relocatable(Isolate* isolate) {
4445 ASSERT(isolate == Isolate::Current());
4446 isolate_ = isolate;
4447 prev_ = isolate->relocatable_top();
4448 isolate->set_relocatable_top(this);
4449}
4450
4451
4452Relocatable::~Relocatable() {
4453 ASSERT(isolate_ == Isolate::Current());
4454 ASSERT_EQ(isolate_->relocatable_top(), this);
4455 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004456}
4457
4458
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004459int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4460 return map->instance_size();
4461}
4462
4463
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004464void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004465 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004466 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004467}
4468
4469
4470template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004471void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004472 StaticVisitor::VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004473 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004474}
4475
4476
4477void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4478 typedef v8::String::ExternalAsciiStringResource Resource;
4479 v->VisitExternalAsciiString(
4480 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4481}
4482
4483
4484template<typename StaticVisitor>
4485void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4486 typedef v8::String::ExternalAsciiStringResource Resource;
4487 StaticVisitor::VisitExternalAsciiString(
4488 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4489}
4490
4491
4492void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4493 typedef v8::String::ExternalStringResource Resource;
4494 v->VisitExternalTwoByteString(
4495 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4496}
4497
4498
4499template<typename StaticVisitor>
4500void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4501 typedef v8::String::ExternalStringResource Resource;
4502 StaticVisitor::VisitExternalTwoByteString(
4503 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4504}
4505
4506#define SLOT_ADDR(obj, offset) \
4507 reinterpret_cast<Object**>((obj)->address() + offset)
4508
4509template<int start_offset, int end_offset, int size>
4510void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4511 HeapObject* obj,
4512 ObjectVisitor* v) {
4513 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4514}
4515
4516
4517template<int start_offset>
4518void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4519 int object_size,
4520 ObjectVisitor* v) {
4521 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4522}
4523
4524#undef SLOT_ADDR
4525
4526
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004527#undef CAST_ACCESSOR
4528#undef INT_ACCESSORS
4529#undef SMI_ACCESSORS
4530#undef ACCESSORS
4531#undef FIELD_ADDR
4532#undef READ_FIELD
4533#undef WRITE_FIELD
4534#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004535#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004536#undef READ_MEMADDR_FIELD
4537#undef WRITE_MEMADDR_FIELD
4538#undef READ_DOUBLE_FIELD
4539#undef WRITE_DOUBLE_FIELD
4540#undef READ_INT_FIELD
4541#undef WRITE_INT_FIELD
4542#undef READ_SHORT_FIELD
4543#undef WRITE_SHORT_FIELD
4544#undef READ_BYTE_FIELD
4545#undef WRITE_BYTE_FIELD
4546
4547
4548} } // namespace v8::internal
4549
4550#endif // V8_OBJECTS_INL_H_