Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Side by Side Diff: src/objects.cc

Issue 6880010: Merge (7265, 7271] from bleeding_edge to experimental/gc branch.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 #include "scopeinfo.h" 45 #include "scopeinfo.h"
46 #include "string-stream.h" 46 #include "string-stream.h"
47 #include "utils.h" 47 #include "utils.h"
48 #include "vm-state-inl.h" 48 #include "vm-state-inl.h"
49 49
50 #ifdef ENABLE_DISASSEMBLER 50 #ifdef ENABLE_DISASSEMBLER
51 #include "disasm.h" 51 #include "disasm.h"
52 #include "disassembler.h" 52 #include "disassembler.h"
53 #endif 53 #endif
54 54
55
56 namespace v8 { 55 namespace v8 {
57 namespace internal { 56 namespace internal {
58 57
59 // Getters and setters are stored in a fixed array property. These are 58 // Getters and setters are stored in a fixed array property. These are
60 // constants for their indices. 59 // constants for their indices.
61 const int kGetterIndex = 0; 60 const int kGetterIndex = 0;
62 const int kSetterIndex = 1; 61 const int kSetterIndex = 1;
63 62
64 63
65 MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor, 64 MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor,
66 Object* value) { 65 Object* value) {
67 Object* result; 66 Object* result;
68 { MaybeObject* maybe_result = Heap::AllocateJSObject(constructor); 67 { MaybeObject* maybe_result =
68 constructor->GetHeap()->AllocateJSObject(constructor);
69 if (!maybe_result->ToObject(&result)) return maybe_result; 69 if (!maybe_result->ToObject(&result)) return maybe_result;
70 } 70 }
71 JSValue::cast(result)->set_value(value); 71 JSValue::cast(result)->set_value(value);
72 return result; 72 return result;
73 } 73 }
74 74
75 75
76 MaybeObject* Object::ToObject(Context* global_context) { 76 MaybeObject* Object::ToObject(Context* global_context) {
77 if (IsNumber()) { 77 if (IsNumber()) {
78 return CreateJSValue(global_context->number_function(), this); 78 return CreateJSValue(global_context->number_function(), this);
79 } else if (IsBoolean()) { 79 } else if (IsBoolean()) {
80 return CreateJSValue(global_context->boolean_function(), this); 80 return CreateJSValue(global_context->boolean_function(), this);
81 } else if (IsString()) { 81 } else if (IsString()) {
82 return CreateJSValue(global_context->string_function(), this); 82 return CreateJSValue(global_context->string_function(), this);
83 } 83 }
84 ASSERT(IsJSObject()); 84 ASSERT(IsJSObject());
85 return this; 85 return this;
86 } 86 }
87 87
88 88
89 MaybeObject* Object::ToObject() { 89 MaybeObject* Object::ToObject() {
90 Context* global_context = Top::context()->global_context();
91 if (IsJSObject()) { 90 if (IsJSObject()) {
92 return this; 91 return this;
93 } else if (IsNumber()) { 92 } else if (IsNumber()) {
93 Isolate* isolate = Isolate::Current();
94 Context* global_context = isolate->context()->global_context();
94 return CreateJSValue(global_context->number_function(), this); 95 return CreateJSValue(global_context->number_function(), this);
95 } else if (IsBoolean()) { 96 } else if (IsBoolean()) {
97 Isolate* isolate = HeapObject::cast(this)->GetIsolate();
98 Context* global_context = isolate->context()->global_context();
96 return CreateJSValue(global_context->boolean_function(), this); 99 return CreateJSValue(global_context->boolean_function(), this);
97 } else if (IsString()) { 100 } else if (IsString()) {
101 Isolate* isolate = HeapObject::cast(this)->GetIsolate();
102 Context* global_context = isolate->context()->global_context();
98 return CreateJSValue(global_context->string_function(), this); 103 return CreateJSValue(global_context->string_function(), this);
99 } 104 }
100 105
101 // Throw a type error. 106 // Throw a type error.
102 return Failure::InternalError(); 107 return Failure::InternalError();
103 } 108 }
104 109
105 110
106 Object* Object::ToBoolean() { 111 Object* Object::ToBoolean() {
107 if (IsTrue()) return Heap::true_value(); 112 if (IsTrue()) return this;
108 if (IsFalse()) return Heap::false_value(); 113 if (IsFalse()) return this;
109 if (IsSmi()) { 114 if (IsSmi()) {
110 return Heap::ToBoolean(Smi::cast(this)->value() != 0); 115 return Isolate::Current()->heap()->ToBoolean(Smi::cast(this)->value() != 0);
111 } 116 }
112 if (IsUndefined() || IsNull()) return Heap::false_value(); 117 if (IsUndefined() || IsNull()) {
118 return HeapObject::cast(this)->GetHeap()->false_value();
119 }
113 // Undetectable object is false 120 // Undetectable object is false
114 if (IsUndetectableObject()) { 121 if (IsUndetectableObject()) {
115 return Heap::false_value(); 122 return HeapObject::cast(this)->GetHeap()->false_value();
116 } 123 }
117 if (IsString()) { 124 if (IsString()) {
118 return Heap::ToBoolean(String::cast(this)->length() != 0); 125 return HeapObject::cast(this)->GetHeap()->ToBoolean(
126 String::cast(this)->length() != 0);
119 } 127 }
120 if (IsHeapNumber()) { 128 if (IsHeapNumber()) {
121 return HeapNumber::cast(this)->HeapNumberToBoolean(); 129 return HeapNumber::cast(this)->HeapNumberToBoolean();
122 } 130 }
123 return Heap::true_value(); 131 return Isolate::Current()->heap()->true_value();
124 } 132 }
125 133
126 134
127 void Object::Lookup(String* name, LookupResult* result) { 135 void Object::Lookup(String* name, LookupResult* result) {
128 if (IsJSObject()) return JSObject::cast(this)->Lookup(name, result); 136 if (IsJSObject()) return JSObject::cast(this)->Lookup(name, result);
129 Object* holder = NULL; 137 Object* holder = NULL;
130 Context* global_context = Top::context()->global_context();
131 if (IsString()) { 138 if (IsString()) {
139 Heap* heap = HeapObject::cast(this)->GetHeap();
140 Context* global_context = heap->isolate()->context()->global_context();
132 holder = global_context->string_function()->instance_prototype(); 141 holder = global_context->string_function()->instance_prototype();
133 } else if (IsNumber()) { 142 } else if (IsNumber()) {
143 Heap* heap = Isolate::Current()->heap();
144 Context* global_context = heap->isolate()->context()->global_context();
134 holder = global_context->number_function()->instance_prototype(); 145 holder = global_context->number_function()->instance_prototype();
135 } else if (IsBoolean()) { 146 } else if (IsBoolean()) {
147 Heap* heap = HeapObject::cast(this)->GetHeap();
148 Context* global_context = heap->isolate()->context()->global_context();
136 holder = global_context->boolean_function()->instance_prototype(); 149 holder = global_context->boolean_function()->instance_prototype();
137 } 150 }
138 ASSERT(holder != NULL); // Cannot handle null or undefined. 151 ASSERT(holder != NULL); // Cannot handle null or undefined.
139 JSObject::cast(holder)->Lookup(name, result); 152 JSObject::cast(holder)->Lookup(name, result);
140 } 153 }
141 154
142 155
143 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, 156 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver,
144 String* name, 157 String* name,
145 PropertyAttributes* attributes) { 158 PropertyAttributes* attributes) {
146 LookupResult result; 159 LookupResult result;
147 Lookup(name, &result); 160 Lookup(name, &result);
148 MaybeObject* value = GetProperty(receiver, &result, name, attributes); 161 MaybeObject* value = GetProperty(receiver, &result, name, attributes);
149 ASSERT(*attributes <= ABSENT); 162 ASSERT(*attributes <= ABSENT);
150 return value; 163 return value;
151 } 164 }
152 165
153 166
154 MaybeObject* Object::GetPropertyWithCallback(Object* receiver, 167 MaybeObject* Object::GetPropertyWithCallback(Object* receiver,
155 Object* structure, 168 Object* structure,
156 String* name, 169 String* name,
157 Object* holder) { 170 Object* holder) {
171 Isolate* isolate = name->GetIsolate();
158 // To accommodate both the old and the new api we switch on the 172 // To accommodate both the old and the new api we switch on the
159 // data structure used to store the callbacks. Eventually proxy 173 // data structure used to store the callbacks. Eventually proxy
160 // callbacks should be phased out. 174 // callbacks should be phased out.
161 if (structure->IsProxy()) { 175 if (structure->IsProxy()) {
162 AccessorDescriptor* callback = 176 AccessorDescriptor* callback =
163 reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy()); 177 reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy());
164 MaybeObject* value = (callback->getter)(receiver, callback->data); 178 MaybeObject* value = (callback->getter)(receiver, callback->data);
165 RETURN_IF_SCHEDULED_EXCEPTION(); 179 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
166 return value; 180 return value;
167 } 181 }
168 182
169 // api style callbacks. 183 // api style callbacks.
170 if (structure->IsAccessorInfo()) { 184 if (structure->IsAccessorInfo()) {
171 AccessorInfo* data = AccessorInfo::cast(structure); 185 AccessorInfo* data = AccessorInfo::cast(structure);
172 Object* fun_obj = data->getter(); 186 Object* fun_obj = data->getter();
173 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); 187 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj);
174 HandleScope scope; 188 HandleScope scope;
175 JSObject* self = JSObject::cast(receiver); 189 JSObject* self = JSObject::cast(receiver);
176 JSObject* holder_handle = JSObject::cast(holder); 190 JSObject* holder_handle = JSObject::cast(holder);
177 Handle<String> key(name); 191 Handle<String> key(name);
178 LOG(ApiNamedPropertyAccess("load", self, name)); 192 LOG(isolate, ApiNamedPropertyAccess("load", self, name));
179 CustomArguments args(data->data(), self, holder_handle); 193 CustomArguments args(isolate, data->data(), self, holder_handle);
180 v8::AccessorInfo info(args.end()); 194 v8::AccessorInfo info(args.end());
181 v8::Handle<v8::Value> result; 195 v8::Handle<v8::Value> result;
182 { 196 {
183 // Leaving JavaScript. 197 // Leaving JavaScript.
184 VMState state(EXTERNAL); 198 VMState state(isolate, EXTERNAL);
185 result = call_fun(v8::Utils::ToLocal(key), info); 199 result = call_fun(v8::Utils::ToLocal(key), info);
186 } 200 }
187 RETURN_IF_SCHEDULED_EXCEPTION(); 201 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
188 if (result.IsEmpty()) return Heap::undefined_value(); 202 if (result.IsEmpty()) {
203 return isolate->heap()->undefined_value();
204 }
189 return *v8::Utils::OpenHandle(*result); 205 return *v8::Utils::OpenHandle(*result);
190 } 206 }
191 207
192 // __defineGetter__ callback 208 // __defineGetter__ callback
193 if (structure->IsFixedArray()) { 209 if (structure->IsFixedArray()) {
194 Object* getter = FixedArray::cast(structure)->get(kGetterIndex); 210 Object* getter = FixedArray::cast(structure)->get(kGetterIndex);
195 if (getter->IsJSFunction()) { 211 if (getter->IsJSFunction()) {
196 return Object::GetPropertyWithDefinedGetter(receiver, 212 return Object::GetPropertyWithDefinedGetter(receiver,
197 JSFunction::cast(getter)); 213 JSFunction::cast(getter));
198 } 214 }
199 // Getter is not a function. 215 // Getter is not a function.
200 return Heap::undefined_value(); 216 return isolate->heap()->undefined_value();
201 } 217 }
202 218
203 UNREACHABLE(); 219 UNREACHABLE();
204 return NULL; 220 return NULL;
205 } 221 }
206 222
207 223
208 MaybeObject* Object::GetPropertyWithDefinedGetter(Object* receiver, 224 MaybeObject* Object::GetPropertyWithDefinedGetter(Object* receiver,
209 JSFunction* getter) { 225 JSFunction* getter) {
210 HandleScope scope; 226 HandleScope scope;
211 Handle<JSFunction> fun(JSFunction::cast(getter)); 227 Handle<JSFunction> fun(JSFunction::cast(getter));
212 Handle<Object> self(receiver); 228 Handle<Object> self(receiver);
213 #ifdef ENABLE_DEBUGGER_SUPPORT 229 #ifdef ENABLE_DEBUGGER_SUPPORT
230 Debug* debug = fun->GetHeap()->isolate()->debug();
214 // Handle stepping into a getter if step into is active. 231 // Handle stepping into a getter if step into is active.
215 if (Debug::StepInActive()) { 232 if (debug->StepInActive()) {
216 Debug::HandleStepIn(fun, Handle<Object>::null(), 0, false); 233 debug->HandleStepIn(fun, Handle<Object>::null(), 0, false);
217 } 234 }
218 #endif 235 #endif
219 bool has_pending_exception; 236 bool has_pending_exception;
220 Handle<Object> result = 237 Handle<Object> result =
221 Execution::Call(fun, self, 0, NULL, &has_pending_exception); 238 Execution::Call(fun, self, 0, NULL, &has_pending_exception);
222 // Check for pending exception and return the result. 239 // Check for pending exception and return the result.
223 if (has_pending_exception) return Failure::Exception(); 240 if (has_pending_exception) return Failure::Exception();
224 return *result; 241 return *result;
225 } 242 }
226 243
227 244
228 // Only deal with CALLBACKS and INTERCEPTOR 245 // Only deal with CALLBACKS and INTERCEPTOR
229 MaybeObject* JSObject::GetPropertyWithFailedAccessCheck( 246 MaybeObject* JSObject::GetPropertyWithFailedAccessCheck(
230 Object* receiver, 247 Object* receiver,
231 LookupResult* result, 248 LookupResult* result,
232 String* name, 249 String* name,
233 PropertyAttributes* attributes) { 250 PropertyAttributes* attributes) {
251 Heap* heap = name->GetHeap();
234 if (result->IsProperty()) { 252 if (result->IsProperty()) {
235 switch (result->type()) { 253 switch (result->type()) {
236 case CALLBACKS: { 254 case CALLBACKS: {
237 // Only allow API accessors. 255 // Only allow API accessors.
238 Object* obj = result->GetCallbackObject(); 256 Object* obj = result->GetCallbackObject();
239 if (obj->IsAccessorInfo()) { 257 if (obj->IsAccessorInfo()) {
240 AccessorInfo* info = AccessorInfo::cast(obj); 258 AccessorInfo* info = AccessorInfo::cast(obj);
241 if (info->all_can_read()) { 259 if (info->all_can_read()) {
242 *attributes = result->GetAttributes(); 260 *attributes = result->GetAttributes();
243 return GetPropertyWithCallback(receiver, 261 return GetPropertyWithCallback(receiver,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 } 293 }
276 break; 294 break;
277 } 295 }
278 default: 296 default:
279 UNREACHABLE(); 297 UNREACHABLE();
280 } 298 }
281 } 299 }
282 300
283 // No accessible property found. 301 // No accessible property found.
284 *attributes = ABSENT; 302 *attributes = ABSENT;
285 Top::ReportFailedAccessCheck(this, v8::ACCESS_GET); 303 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET);
286 return Heap::undefined_value(); 304 return heap->undefined_value();
287 } 305 }
288 306
289 307
290 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( 308 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
291 Object* receiver, 309 Object* receiver,
292 LookupResult* result, 310 LookupResult* result,
293 String* name, 311 String* name,
294 bool continue_search) { 312 bool continue_search) {
313 Heap* heap = name->GetHeap();
295 if (result->IsProperty()) { 314 if (result->IsProperty()) {
296 switch (result->type()) { 315 switch (result->type()) {
297 case CALLBACKS: { 316 case CALLBACKS: {
298 // Only allow API accessors. 317 // Only allow API accessors.
299 Object* obj = result->GetCallbackObject(); 318 Object* obj = result->GetCallbackObject();
300 if (obj->IsAccessorInfo()) { 319 if (obj->IsAccessorInfo()) {
301 AccessorInfo* info = AccessorInfo::cast(obj); 320 AccessorInfo* info = AccessorInfo::cast(obj);
302 if (info->all_can_read()) { 321 if (info->all_can_read()) {
303 return result->GetAttributes(); 322 return result->GetAttributes();
304 } 323 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 continue_search); 357 continue_search);
339 } 358 }
340 break; 359 break;
341 } 360 }
342 361
343 default: 362 default:
344 UNREACHABLE(); 363 UNREACHABLE();
345 } 364 }
346 } 365 }
347 366
348 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); 367 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
349 return ABSENT; 368 return ABSENT;
350 } 369 }
351 370
352 371
353 Object* JSObject::GetNormalizedProperty(LookupResult* result) { 372 Object* JSObject::GetNormalizedProperty(LookupResult* result) {
354 ASSERT(!HasFastProperties()); 373 ASSERT(!HasFastProperties());
355 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); 374 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
356 if (IsGlobalObject()) { 375 if (IsGlobalObject()) {
357 value = JSGlobalPropertyCell::cast(value)->value(); 376 value = JSGlobalPropertyCell::cast(value)->value();
358 } 377 }
(...skipping 13 matching lines...) Expand all
372 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); 391 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value);
373 } 392 }
374 return value; 393 return value;
375 } 394 }
376 395
377 396
378 MaybeObject* JSObject::SetNormalizedProperty(String* name, 397 MaybeObject* JSObject::SetNormalizedProperty(String* name,
379 Object* value, 398 Object* value,
380 PropertyDetails details) { 399 PropertyDetails details) {
381 ASSERT(!HasFastProperties()); 400 ASSERT(!HasFastProperties());
401 Heap* heap = name->GetHeap();
382 int entry = property_dictionary()->FindEntry(name); 402 int entry = property_dictionary()->FindEntry(name);
383 if (entry == StringDictionary::kNotFound) { 403 if (entry == StringDictionary::kNotFound) {
384 Object* store_value = value; 404 Object* store_value = value;
385 if (IsGlobalObject()) { 405 if (IsGlobalObject()) {
386 { MaybeObject* maybe_store_value = 406 MaybeObject* maybe_store_value =
387 Heap::AllocateJSGlobalPropertyCell(value); 407 heap->AllocateJSGlobalPropertyCell(value);
388 if (!maybe_store_value->ToObject(&store_value)) { 408 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value;
389 return maybe_store_value;
390 }
391 }
392 } 409 }
393 Object* dict; 410 Object* dict;
394 { MaybeObject* maybe_dict = 411 { MaybeObject* maybe_dict =
395 property_dictionary()->Add(name, store_value, details); 412 property_dictionary()->Add(name, store_value, details);
396 if (!maybe_dict->ToObject(&dict)) return maybe_dict; 413 if (!maybe_dict->ToObject(&dict)) return maybe_dict;
397 } 414 }
398 set_properties(StringDictionary::cast(dict)); 415 set_properties(StringDictionary::cast(dict));
399 return value; 416 return value;
400 } 417 }
401 // Preserve enumeration index. 418 // Preserve enumeration index.
402 details = PropertyDetails(details.attributes(), 419 details = PropertyDetails(details.attributes(),
403 details.type(), 420 details.type(),
404 property_dictionary()->DetailsAt(entry).index()); 421 property_dictionary()->DetailsAt(entry).index());
405 if (IsGlobalObject()) { 422 if (IsGlobalObject()) {
406 JSGlobalPropertyCell* cell = 423 JSGlobalPropertyCell* cell =
407 JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry)); 424 JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry));
408 cell->set_value(value); 425 cell->set_value(value);
409 // Please note we have to update the property details. 426 // Please note we have to update the property details.
410 property_dictionary()->DetailsAtPut(entry, details); 427 property_dictionary()->DetailsAtPut(entry, details);
411 } else { 428 } else {
412 property_dictionary()->SetEntry(entry, name, value, details); 429 property_dictionary()->SetEntry(entry, name, value, details);
413 } 430 }
414 return value; 431 return value;
415 } 432 }
416 433
417 434
418 MaybeObject* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) { 435 MaybeObject* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) {
419 ASSERT(!HasFastProperties()); 436 ASSERT(!HasFastProperties());
437 Heap* heap = GetHeap();
420 StringDictionary* dictionary = property_dictionary(); 438 StringDictionary* dictionary = property_dictionary();
421 int entry = dictionary->FindEntry(name); 439 int entry = dictionary->FindEntry(name);
422 if (entry != StringDictionary::kNotFound) { 440 if (entry != StringDictionary::kNotFound) {
423 // If we have a global object set the cell to the hole. 441 // If we have a global object set the cell to the hole.
424 if (IsGlobalObject()) { 442 if (IsGlobalObject()) {
425 PropertyDetails details = dictionary->DetailsAt(entry); 443 PropertyDetails details = dictionary->DetailsAt(entry);
426 if (details.IsDontDelete()) { 444 if (details.IsDontDelete()) {
427 if (mode != FORCE_DELETION) return Heap::false_value(); 445 if (mode != FORCE_DELETION) return heap->false_value();
428 // When forced to delete global properties, we have to make a 446 // When forced to delete global properties, we have to make a
429 // map change to invalidate any ICs that think they can load 447 // map change to invalidate any ICs that think they can load
430 // from the DontDelete cell without checking if it contains 448 // from the DontDelete cell without checking if it contains
431 // the hole value. 449 // the hole value.
432 Object* new_map; 450 Object* new_map;
433 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); 451 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors();
434 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; 452 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
435 } 453 }
436 set_map(Map::cast(new_map)); 454 set_map(Map::cast(new_map));
437 } 455 }
438 JSGlobalPropertyCell* cell = 456 JSGlobalPropertyCell* cell =
439 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry)); 457 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry));
440 cell->set_value(Heap::the_hole_value()); 458 cell->set_value(heap->the_hole_value());
441 dictionary->DetailsAtPut(entry, details.AsDeleted()); 459 dictionary->DetailsAtPut(entry, details.AsDeleted());
442 } else { 460 } else {
443 return dictionary->DeleteProperty(entry, mode); 461 return dictionary->DeleteProperty(entry, mode);
444 } 462 }
445 } 463 }
446 return Heap::true_value(); 464 return heap->true_value();
447 } 465 }
448 466
449 467
450 bool JSObject::IsDirty() { 468 bool JSObject::IsDirty() {
451 Object* cons_obj = map()->constructor(); 469 Object* cons_obj = map()->constructor();
452 if (!cons_obj->IsJSFunction()) 470 if (!cons_obj->IsJSFunction())
453 return true; 471 return true;
454 JSFunction* fun = JSFunction::cast(cons_obj); 472 JSFunction* fun = JSFunction::cast(cons_obj);
455 if (!fun->shared()->IsApiFunction()) 473 if (!fun->shared()->IsApiFunction())
456 return true; 474 return true;
457 // If the object is fully fast case and has the same map it was 475 // If the object is fully fast case and has the same map it was
458 // created with then no changes can have been made to it. 476 // created with then no changes can have been made to it.
459 return map() != fun->initial_map() 477 return map() != fun->initial_map()
460 || !HasFastElements() 478 || !HasFastElements()
461 || !HasFastProperties(); 479 || !HasFastProperties();
462 } 480 }
463 481
464 482
465 MaybeObject* Object::GetProperty(Object* receiver, 483 MaybeObject* Object::GetProperty(Object* receiver,
466 LookupResult* result, 484 LookupResult* result,
467 String* name, 485 String* name,
468 PropertyAttributes* attributes) { 486 PropertyAttributes* attributes) {
469 // Make sure that the top context does not change when doing 487 // Make sure that the top context does not change when doing
470 // callbacks or interceptor calls. 488 // callbacks or interceptor calls.
471 AssertNoContextChange ncc; 489 AssertNoContextChange ncc;
490 Heap* heap = name->GetHeap();
472 491
473 // Traverse the prototype chain from the current object (this) to 492 // Traverse the prototype chain from the current object (this) to
474 // the holder and check for access rights. This avoid traversing the 493 // the holder and check for access rights. This avoid traversing the
475 // objects more than once in case of interceptors, because the 494 // objects more than once in case of interceptors, because the
476 // holder will always be the interceptor holder and the search may 495 // holder will always be the interceptor holder and the search may
477 // only continue with a current object just after the interceptor 496 // only continue with a current object just after the interceptor
478 // holder in the prototype chain. 497 // holder in the prototype chain.
479 Object* last = result->IsProperty() ? result->holder() : Heap::null_value(); 498 Object* last = result->IsProperty() ? result->holder() : heap->null_value();
480 for (Object* current = this; true; current = current->GetPrototype()) { 499 for (Object* current = this; true; current = current->GetPrototype()) {
481 if (current->IsAccessCheckNeeded()) { 500 if (current->IsAccessCheckNeeded()) {
482 // Check if we're allowed to read from the current object. Note 501 // Check if we're allowed to read from the current object. Note
483 // that even though we may not actually end up loading the named 502 // that even though we may not actually end up loading the named
484 // property from the current object, we still check that we have 503 // property from the current object, we still check that we have
485 // access to it. 504 // access to it.
486 JSObject* checked = JSObject::cast(current); 505 JSObject* checked = JSObject::cast(current);
487 if (!Top::MayNamedAccess(checked, name, v8::ACCESS_GET)) { 506 if (!heap->isolate()->MayNamedAccess(checked, name, v8::ACCESS_GET)) {
488 return checked->GetPropertyWithFailedAccessCheck(receiver, 507 return checked->GetPropertyWithFailedAccessCheck(receiver,
489 result, 508 result,
490 name, 509 name,
491 attributes); 510 attributes);
492 } 511 }
493 } 512 }
494 // Stop traversing the chain once we reach the last object in the 513 // Stop traversing the chain once we reach the last object in the
495 // chain; either the holder of the result or null in case of an 514 // chain; either the holder of the result or null in case of an
496 // absent property. 515 // absent property.
497 if (current == last) break; 516 if (current == last) break;
498 } 517 }
499 518
500 if (!result->IsProperty()) { 519 if (!result->IsProperty()) {
501 *attributes = ABSENT; 520 *attributes = ABSENT;
502 return Heap::undefined_value(); 521 return heap->undefined_value();
503 } 522 }
504 *attributes = result->GetAttributes(); 523 *attributes = result->GetAttributes();
505 Object* value; 524 Object* value;
506 JSObject* holder = result->holder(); 525 JSObject* holder = result->holder();
507 switch (result->type()) { 526 switch (result->type()) {
508 case NORMAL: 527 case NORMAL:
509 value = holder->GetNormalizedProperty(result); 528 value = holder->GetNormalizedProperty(result);
510 ASSERT(!value->IsTheHole() || result->IsReadOnly()); 529 ASSERT(!value->IsTheHole() || result->IsReadOnly());
511 return value->IsTheHole() ? Heap::undefined_value() : value; 530 return value->IsTheHole() ? heap->undefined_value() : value;
512 case FIELD: 531 case FIELD:
513 value = holder->FastPropertyAt(result->GetFieldIndex()); 532 value = holder->FastPropertyAt(result->GetFieldIndex());
514 ASSERT(!value->IsTheHole() || result->IsReadOnly()); 533 ASSERT(!value->IsTheHole() || result->IsReadOnly());
515 return value->IsTheHole() ? Heap::undefined_value() : value; 534 return value->IsTheHole() ? heap->undefined_value() : value;
516 case CONSTANT_FUNCTION: 535 case CONSTANT_FUNCTION:
517 return result->GetConstantFunction(); 536 return result->GetConstantFunction();
518 case CALLBACKS: 537 case CALLBACKS:
519 return GetPropertyWithCallback(receiver, 538 return GetPropertyWithCallback(receiver,
520 result->GetCallbackObject(), 539 result->GetCallbackObject(),
521 name, 540 name,
522 holder); 541 holder);
523 case INTERCEPTOR: { 542 case INTERCEPTOR: {
524 JSObject* recvr = JSObject::cast(receiver); 543 JSObject* recvr = JSObject::cast(receiver);
525 return holder->GetPropertyWithInterceptor(recvr, name, attributes); 544 return holder->GetPropertyWithInterceptor(recvr, name, attributes);
526 } 545 }
527 default: 546 default:
528 UNREACHABLE(); 547 UNREACHABLE();
529 return NULL; 548 return NULL;
530 } 549 }
531 } 550 }
532 551
533 552
534 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { 553 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) {
535 if (IsJSObject()) { 554 if (IsJSObject()) {
536 return JSObject::cast(this)->GetElementWithReceiver(receiver, index); 555 return JSObject::cast(this)->GetElementWithReceiver(receiver, index);
537 } 556 }
538 557
539 Object* holder = NULL; 558 Object* holder = NULL;
540 Context* global_context = Top::context()->global_context(); 559 Context* global_context = Isolate::Current()->context()->global_context();
541 if (IsString()) { 560 if (IsString()) {
542 holder = global_context->string_function()->instance_prototype(); 561 holder = global_context->string_function()->instance_prototype();
543 } else if (IsNumber()) { 562 } else if (IsNumber()) {
544 holder = global_context->number_function()->instance_prototype(); 563 holder = global_context->number_function()->instance_prototype();
545 } else if (IsBoolean()) { 564 } else if (IsBoolean()) {
546 holder = global_context->boolean_function()->instance_prototype(); 565 holder = global_context->boolean_function()->instance_prototype();
547 } else { 566 } else {
548 // Undefined and null have no indexed properties. 567 // Undefined and null have no indexed properties.
549 ASSERT(IsUndefined() || IsNull()); 568 ASSERT(IsUndefined() || IsNull());
550 return Heap::undefined_value(); 569 return HEAP->undefined_value();
551 } 570 }
552 571
553 return JSObject::cast(holder)->GetElementWithReceiver(receiver, index); 572 return JSObject::cast(holder)->GetElementWithReceiver(receiver, index);
554 } 573 }
555 574
556 575
557 Object* Object::GetPrototype() { 576 Object* Object::GetPrototype() {
558 // The object is either a number, a string, a boolean, or a real JS object. 577 // The object is either a number, a string, a boolean, or a real JS object.
559 if (IsJSObject()) return JSObject::cast(this)->map()->prototype(); 578 if (IsJSObject()) return JSObject::cast(this)->map()->prototype();
560 Context* context = Top::context()->global_context(); 579 Heap* heap = Isolate::Current()->heap();
580 Context* context = heap->isolate()->context()->global_context();
561 581
562 if (IsNumber()) return context->number_function()->instance_prototype(); 582 if (IsNumber()) return context->number_function()->instance_prototype();
563 if (IsString()) return context->string_function()->instance_prototype(); 583 if (IsString()) return context->string_function()->instance_prototype();
564 if (IsBoolean()) { 584 if (IsBoolean()) {
565 return context->boolean_function()->instance_prototype(); 585 return context->boolean_function()->instance_prototype();
566 } else { 586 } else {
567 return Heap::null_value(); 587 return heap->null_value();
568 } 588 }
569 } 589 }
570 590
571 591
572 void Object::ShortPrint(FILE* out) { 592 void Object::ShortPrint(FILE* out) {
573 HeapStringAllocator allocator; 593 HeapStringAllocator allocator;
574 StringStream accumulator(&allocator); 594 StringStream accumulator(&allocator);
575 ShortPrint(&accumulator); 595 ShortPrint(&accumulator);
576 accumulator.OutputToFile(out); 596 accumulator.OutputToFile(out);
577 } 597 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 return false; 651 return false;
632 } 652 }
633 653
634 654
635 MaybeObject* String::SlowTryFlatten(PretenureFlag pretenure) { 655 MaybeObject* String::SlowTryFlatten(PretenureFlag pretenure) {
636 #ifdef DEBUG 656 #ifdef DEBUG
637 // Do not attempt to flatten in debug mode when allocation is not 657 // Do not attempt to flatten in debug mode when allocation is not
638 // allowed. This is to avoid an assertion failure when allocating. 658 // allowed. This is to avoid an assertion failure when allocating.
639 // Flattening strings is the only case where we always allow 659 // Flattening strings is the only case where we always allow
640 // allocation because no GC is performed if the allocation fails. 660 // allocation because no GC is performed if the allocation fails.
641 if (!Heap::IsAllocationAllowed()) return this; 661 if (!HEAP->IsAllocationAllowed()) return this;
642 #endif 662 #endif
643 663
664 Heap* heap = GetHeap();
644 switch (StringShape(this).representation_tag()) { 665 switch (StringShape(this).representation_tag()) {
645 case kConsStringTag: { 666 case kConsStringTag: {
646 ConsString* cs = ConsString::cast(this); 667 ConsString* cs = ConsString::cast(this);
647 if (cs->second()->length() == 0) { 668 if (cs->second()->length() == 0) {
648 return cs->first(); 669 return cs->first();
649 } 670 }
650 // There's little point in putting the flat string in new space if the 671 // There's little point in putting the flat string in new space if the
651 // cons string is in old space. It can never get GCed until there is 672 // cons string is in old space. It can never get GCed until there is
652 // an old space GC. 673 // an old space GC.
653 PretenureFlag tenure = Heap::InNewSpace(this) ? pretenure : TENURED; 674 PretenureFlag tenure = heap->InNewSpace(this) ? pretenure : TENURED;
654 int len = length(); 675 int len = length();
655 Object* object; 676 Object* object;
656 String* result; 677 String* result;
657 if (IsAsciiRepresentation()) { 678 if (IsAsciiRepresentation()) {
658 { MaybeObject* maybe_object = Heap::AllocateRawAsciiString(len, tenure); 679 { MaybeObject* maybe_object = heap->AllocateRawAsciiString(len, tenure);
659 if (!maybe_object->ToObject(&object)) return maybe_object; 680 if (!maybe_object->ToObject(&object)) return maybe_object;
660 } 681 }
661 result = String::cast(object); 682 result = String::cast(object);
662 String* first = cs->first(); 683 String* first = cs->first();
663 int first_length = first->length(); 684 int first_length = first->length();
664 char* dest = SeqAsciiString::cast(result)->GetChars(); 685 char* dest = SeqAsciiString::cast(result)->GetChars();
665 WriteToFlat(first, dest, 0, first_length); 686 WriteToFlat(first, dest, 0, first_length);
666 String* second = cs->second(); 687 String* second = cs->second();
667 WriteToFlat(second, 688 WriteToFlat(second,
668 dest + first_length, 689 dest + first_length,
669 0, 690 0,
670 len - first_length); 691 len - first_length);
671 } else { 692 } else {
672 { MaybeObject* maybe_object = 693 { MaybeObject* maybe_object =
673 Heap::AllocateRawTwoByteString(len, tenure); 694 heap->AllocateRawTwoByteString(len, tenure);
674 if (!maybe_object->ToObject(&object)) return maybe_object; 695 if (!maybe_object->ToObject(&object)) return maybe_object;
675 } 696 }
676 result = String::cast(object); 697 result = String::cast(object);
677 uc16* dest = SeqTwoByteString::cast(result)->GetChars(); 698 uc16* dest = SeqTwoByteString::cast(result)->GetChars();
678 String* first = cs->first(); 699 String* first = cs->first();
679 int first_length = first->length(); 700 int first_length = first->length();
680 WriteToFlat(first, dest, 0, first_length); 701 WriteToFlat(first, dest, 0, first_length);
681 String* second = cs->second(); 702 String* second = cs->second();
682 WriteToFlat(second, 703 WriteToFlat(second,
683 dest + first_length, 704 dest + first_length,
684 0, 705 0,
685 len - first_length); 706 len - first_length);
686 } 707 }
687 cs->set_first(result); 708 cs->set_first(result);
688 cs->set_second(Heap::empty_string()); 709 cs->set_second(heap->empty_string());
689 return result; 710 return result;
690 } 711 }
691 default: 712 default:
692 return this; 713 return this;
693 } 714 }
694 } 715 }
695 716
696 717
697 bool String::MakeExternal(v8::String::ExternalStringResource* resource) { 718 bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
698 // Externalizing twice leaks the external resource, so it's 719 // Externalizing twice leaks the external resource, so it's
699 // prohibited by the API. 720 // prohibited by the API.
700 ASSERT(!this->IsExternalString()); 721 ASSERT(!this->IsExternalString());
701 #ifdef DEBUG 722 #ifdef DEBUG
702 if (FLAG_enable_slow_asserts) { 723 if (FLAG_enable_slow_asserts) {
703 // Assert that the resource and the string are equivalent. 724 // Assert that the resource and the string are equivalent.
704 ASSERT(static_cast<size_t>(this->length()) == resource->length()); 725 ASSERT(static_cast<size_t>(this->length()) == resource->length());
705 ScopedVector<uc16> smart_chars(this->length()); 726 ScopedVector<uc16> smart_chars(this->length());
706 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); 727 String::WriteToFlat(this, smart_chars.start(), 0, this->length());
707 ASSERT(memcmp(smart_chars.start(), 728 ASSERT(memcmp(smart_chars.start(),
708 resource->data(), 729 resource->data(),
709 resource->length() * sizeof(smart_chars[0])) == 0); 730 resource->length() * sizeof(smart_chars[0])) == 0);
710 } 731 }
711 #endif // DEBUG 732 #endif // DEBUG
712 733 Heap* heap = GetHeap();
713 int size = this->Size(); // Byte size of the original string. 734 int size = this->Size(); // Byte size of the original string.
714 if (size < ExternalString::kSize) { 735 if (size < ExternalString::kSize) {
715 // The string is too small to fit an external String in its place. This can 736 // The string is too small to fit an external String in its place. This can
716 // only happen for zero length strings. 737 // only happen for zero length strings.
717 return false; 738 return false;
718 } 739 }
719 ASSERT(size >= ExternalString::kSize); 740 ASSERT(size >= ExternalString::kSize);
720 bool is_ascii = this->IsAsciiRepresentation(); 741 bool is_ascii = this->IsAsciiRepresentation();
721 bool is_symbol = this->IsSymbol(); 742 bool is_symbol = this->IsSymbol();
722 int length = this->length(); 743 int length = this->length();
723 int hash_field = this->hash_field(); 744 int hash_field = this->hash_field();
724 745
725 // Morph the object to an external string by adjusting the map and 746 // Morph the object to an external string by adjusting the map and
726 // reinitializing the fields. 747 // reinitializing the fields.
727 this->set_map(is_ascii ? 748 this->set_map(is_ascii ?
728 Heap::external_string_with_ascii_data_map() : 749 heap->external_string_with_ascii_data_map() :
729 Heap::external_string_map()); 750 heap->external_string_map());
730 ExternalTwoByteString* self = ExternalTwoByteString::cast(this); 751 ExternalTwoByteString* self = ExternalTwoByteString::cast(this);
731 self->set_length(length); 752 self->set_length(length);
732 self->set_hash_field(hash_field); 753 self->set_hash_field(hash_field);
733 self->set_resource(resource); 754 self->set_resource(resource);
734 // Additionally make the object into an external symbol if the original string 755 // Additionally make the object into an external symbol if the original string
735 // was a symbol to start with. 756 // was a symbol to start with.
736 if (is_symbol) { 757 if (is_symbol) {
737 self->Hash(); // Force regeneration of the hash value. 758 self->Hash(); // Force regeneration of the hash value.
738 // Now morph this external string into a external symbol. 759 // Now morph this external string into a external symbol.
739 this->set_map(is_ascii ? 760 this->set_map(is_ascii ?
740 Heap::external_symbol_with_ascii_data_map() : 761 heap->external_symbol_with_ascii_data_map() :
741 Heap::external_symbol_map()); 762 heap->external_symbol_map());
742 } 763 }
743 764
744 // Fill the remainder of the string with dead wood. 765 // Fill the remainder of the string with dead wood.
745 int new_size = this->Size(); // Byte size of the external String object. 766 int new_size = this->Size(); // Byte size of the external String object.
746 Heap::CreateFillerObjectAt(this->address() + new_size, size - new_size); 767 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size);
747 return true; 768 return true;
748 } 769 }
749 770
750 771
751 bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) { 772 bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) {
752 #ifdef DEBUG 773 #ifdef DEBUG
753 if (FLAG_enable_slow_asserts) { 774 if (FLAG_enable_slow_asserts) {
754 // Assert that the resource and the string are equivalent. 775 // Assert that the resource and the string are equivalent.
755 ASSERT(static_cast<size_t>(this->length()) == resource->length()); 776 ASSERT(static_cast<size_t>(this->length()) == resource->length());
756 ScopedVector<char> smart_chars(this->length()); 777 ScopedVector<char> smart_chars(this->length());
757 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); 778 String::WriteToFlat(this, smart_chars.start(), 0, this->length());
758 ASSERT(memcmp(smart_chars.start(), 779 ASSERT(memcmp(smart_chars.start(),
759 resource->data(), 780 resource->data(),
760 resource->length() * sizeof(smart_chars[0])) == 0); 781 resource->length() * sizeof(smart_chars[0])) == 0);
761 } 782 }
762 #endif // DEBUG 783 #endif // DEBUG
763 784 Heap* heap = GetHeap();
764 int size = this->Size(); // Byte size of the original string. 785 int size = this->Size(); // Byte size of the original string.
765 if (size < ExternalString::kSize) { 786 if (size < ExternalString::kSize) {
766 // The string is too small to fit an external String in its place. This can 787 // The string is too small to fit an external String in its place. This can
767 // only happen for zero length strings. 788 // only happen for zero length strings.
768 return false; 789 return false;
769 } 790 }
770 ASSERT(size >= ExternalString::kSize); 791 ASSERT(size >= ExternalString::kSize);
771 bool is_symbol = this->IsSymbol(); 792 bool is_symbol = this->IsSymbol();
772 int length = this->length(); 793 int length = this->length();
773 int hash_field = this->hash_field(); 794 int hash_field = this->hash_field();
774 795
775 // Morph the object to an external string by adjusting the map and 796 // Morph the object to an external string by adjusting the map and
776 // reinitializing the fields. 797 // reinitializing the fields.
777 this->set_map(Heap::external_ascii_string_map()); 798 this->set_map(heap->external_ascii_string_map());
778 ExternalAsciiString* self = ExternalAsciiString::cast(this); 799 ExternalAsciiString* self = ExternalAsciiString::cast(this);
779 self->set_length(length); 800 self->set_length(length);
780 self->set_hash_field(hash_field); 801 self->set_hash_field(hash_field);
781 self->set_resource(resource); 802 self->set_resource(resource);
782 // Additionally make the object into an external symbol if the original string 803 // Additionally make the object into an external symbol if the original string
783 // was a symbol to start with. 804 // was a symbol to start with.
784 if (is_symbol) { 805 if (is_symbol) {
785 self->Hash(); // Force regeneration of the hash value. 806 self->Hash(); // Force regeneration of the hash value.
786 // Now morph this external string into a external symbol. 807 // Now morph this external string into a external symbol.
787 this->set_map(Heap::external_ascii_symbol_map()); 808 this->set_map(heap->external_ascii_symbol_map());
788 } 809 }
789 810
790 // Fill the remainder of the string with dead wood. 811 // Fill the remainder of the string with dead wood.
791 int new_size = this->Size(); // Byte size of the external String object. 812 int new_size = this->Size(); // Byte size of the external String object.
792 Heap::CreateFillerObjectAt(this->address() + new_size, size - new_size); 813 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size);
793 return true; 814 return true;
794 } 815 }
795 816
796 817
797 void String::StringShortPrint(StringStream* accumulator) { 818 void String::StringShortPrint(StringStream* accumulator) {
798 int len = length(); 819 int len = length();
799 if (len > kMaxShortPrintLength) { 820 if (len > kMaxShortPrintLength) {
800 accumulator->Add("<Very long string[%u]>", len); 821 accumulator->Add("<Very long string[%u]>", len);
801 return; 822 return;
802 } 823 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 } 902 }
882 } 903 }
883 if (!printed) { 904 if (!printed) {
884 accumulator->Add("<JS Function>"); 905 accumulator->Add("<JS Function>");
885 } 906 }
886 break; 907 break;
887 } 908 }
888 // All other JSObjects are rather similar to each other (JSObject, 909 // All other JSObjects are rather similar to each other (JSObject,
889 // JSGlobalProxy, JSGlobalObject, JSUndetectableObject, JSValue). 910 // JSGlobalProxy, JSGlobalObject, JSUndetectableObject, JSValue).
890 default: { 911 default: {
912 Heap* heap = GetHeap();
891 Object* constructor = map()->constructor(); 913 Object* constructor = map()->constructor();
892 bool printed = false; 914 bool printed = false;
893 if (constructor->IsHeapObject() && 915 if (constructor->IsHeapObject() &&
894 !Heap::Contains(HeapObject::cast(constructor))) { 916 !heap->Contains(HeapObject::cast(constructor))) {
895 accumulator->Add("!!!INVALID CONSTRUCTOR!!!"); 917 accumulator->Add("!!!INVALID CONSTRUCTOR!!!");
896 } else { 918 } else {
897 bool global_object = IsJSGlobalProxy(); 919 bool global_object = IsJSGlobalProxy();
898 if (constructor->IsJSFunction()) { 920 if (constructor->IsJSFunction()) {
899 if (!Heap::Contains(JSFunction::cast(constructor)->shared())) { 921 if (!heap->Contains(JSFunction::cast(constructor)->shared())) {
900 accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!"); 922 accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!");
901 } else { 923 } else {
902 Object* constructor_name = 924 Object* constructor_name =
903 JSFunction::cast(constructor)->shared()->name(); 925 JSFunction::cast(constructor)->shared()->name();
904 if (constructor_name->IsString()) { 926 if (constructor_name->IsString()) {
905 String* str = String::cast(constructor_name); 927 String* str = String::cast(constructor_name);
906 if (str->length() > 0) { 928 if (str->length() > 0) {
907 bool vowel = AnWord(str); 929 bool vowel = AnWord(str);
908 accumulator->Add("<%sa%s ", 930 accumulator->Add("<%sa%s ",
909 global_object ? "Global Object: " : "", 931 global_object ? "Global Object: " : "",
(...skipping 14 matching lines...) Expand all
924 JSValue::cast(this)->value()->ShortPrint(accumulator); 946 JSValue::cast(this)->value()->ShortPrint(accumulator);
925 } 947 }
926 accumulator->Put('>'); 948 accumulator->Put('>');
927 break; 949 break;
928 } 950 }
929 } 951 }
930 } 952 }
931 953
932 954
933 void HeapObject::HeapObjectShortPrint(StringStream* accumulator) { 955 void HeapObject::HeapObjectShortPrint(StringStream* accumulator) {
934 // if (!Heap::InNewSpace(this)) PrintF("*", this); 956 // if (!HEAP->InNewSpace(this)) PrintF("*", this);
935 if (!Heap::Contains(this)) { 957 Heap* heap = GetHeap();
958 if (!heap->Contains(this)) {
936 accumulator->Add("!!!INVALID POINTER!!!"); 959 accumulator->Add("!!!INVALID POINTER!!!");
937 return; 960 return;
938 } 961 }
939 if (!Heap::Contains(map())) { 962 if (!heap->Contains(map())) {
940 accumulator->Add("!!!INVALID MAP!!!"); 963 accumulator->Add("!!!INVALID MAP!!!");
941 return; 964 return;
942 } 965 }
943 966
944 accumulator->Add("%p ", this); 967 accumulator->Add("%p ", this);
945 968
946 if (IsString()) { 969 if (IsString()) {
947 String::cast(this)->StringShortPrint(accumulator); 970 String::cast(this)->StringShortPrint(accumulator);
948 return; 971 return;
949 } 972 }
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1148 // NaN, +0, and -0 should return the false object 1171 // NaN, +0, and -0 should return the false object
1149 #if __BYTE_ORDER == __LITTLE_ENDIAN 1172 #if __BYTE_ORDER == __LITTLE_ENDIAN
1150 union IeeeDoubleLittleEndianArchType u; 1173 union IeeeDoubleLittleEndianArchType u;
1151 #elif __BYTE_ORDER == __BIG_ENDIAN 1174 #elif __BYTE_ORDER == __BIG_ENDIAN
1152 union IeeeDoubleBigEndianArchType u; 1175 union IeeeDoubleBigEndianArchType u;
1153 #endif 1176 #endif
1154 u.d = value(); 1177 u.d = value();
1155 if (u.bits.exp == 2047) { 1178 if (u.bits.exp == 2047) {
1156 // Detect NaN for IEEE double precision floating point. 1179 // Detect NaN for IEEE double precision floating point.
1157 if ((u.bits.man_low | u.bits.man_high) != 0) 1180 if ((u.bits.man_low | u.bits.man_high) != 0)
1158 return Heap::false_value(); 1181 return GetHeap()->false_value();
1159 } 1182 }
1160 if (u.bits.exp == 0) { 1183 if (u.bits.exp == 0) {
1161 // Detect +0, and -0 for IEEE double precision floating point. 1184 // Detect +0, and -0 for IEEE double precision floating point.
1162 if ((u.bits.man_low | u.bits.man_high) == 0) 1185 if ((u.bits.man_low | u.bits.man_high) == 0)
1163 return Heap::false_value(); 1186 return GetHeap()->false_value();
1164 } 1187 }
1165 return Heap::true_value(); 1188 return GetHeap()->true_value();
1166 } 1189 }
1167 1190
1168 1191
1169 void HeapNumber::HeapNumberPrint(FILE* out) { 1192 void HeapNumber::HeapNumberPrint(FILE* out) {
1170 PrintF(out, "%.16g", Number()); 1193 PrintF(out, "%.16g", Number());
1171 } 1194 }
1172 1195
1173 1196
1174 void HeapNumber::HeapNumberPrint(StringStream* accumulator) { 1197 void HeapNumber::HeapNumberPrint(StringStream* accumulator) {
1175 // The Windows version of vsnprintf can allocate when printing a %g string 1198 // The Windows version of vsnprintf can allocate when printing a %g string
1176 // into a buffer that may not be big enough. We don't want random memory 1199 // into a buffer that may not be big enough. We don't want random memory
1177 // allocation when producing post-crash stack traces, so we print into a 1200 // allocation when producing post-crash stack traces, so we print into a
1178 // buffer that is plenty big enough for any floating point number, then 1201 // buffer that is plenty big enough for any floating point number, then
1179 // print that using vsnprintf (which may truncate but never allocate if 1202 // print that using vsnprintf (which may truncate but never allocate if
1180 // there is no more space in the buffer). 1203 // there is no more space in the buffer).
1181 EmbeddedVector<char, 100> buffer; 1204 EmbeddedVector<char, 100> buffer;
1182 OS::SNPrintF(buffer, "%.16g", Number()); 1205 OS::SNPrintF(buffer, "%.16g", Number());
1183 accumulator->Add("%s", buffer.start()); 1206 accumulator->Add("%s", buffer.start());
1184 } 1207 }
1185 1208
1186 1209
1187 String* JSObject::class_name() { 1210 String* JSObject::class_name() {
1188 if (IsJSFunction()) { 1211 if (IsJSFunction()) {
1189 return Heap::function_class_symbol(); 1212 return GetHeap()->function_class_symbol();
1190 } 1213 }
1191 if (map()->constructor()->IsJSFunction()) { 1214 if (map()->constructor()->IsJSFunction()) {
1192 JSFunction* constructor = JSFunction::cast(map()->constructor()); 1215 JSFunction* constructor = JSFunction::cast(map()->constructor());
1193 return String::cast(constructor->shared()->instance_class_name()); 1216 return String::cast(constructor->shared()->instance_class_name());
1194 } 1217 }
1195 // If the constructor is not present, return "Object". 1218 // If the constructor is not present, return "Object".
1196 return Heap::Object_symbol(); 1219 return GetHeap()->Object_symbol();
1197 } 1220 }
1198 1221
1199 1222
1200 String* JSObject::constructor_name() { 1223 String* JSObject::constructor_name() {
1201 if (map()->constructor()->IsJSFunction()) { 1224 if (map()->constructor()->IsJSFunction()) {
1202 JSFunction* constructor = JSFunction::cast(map()->constructor()); 1225 JSFunction* constructor = JSFunction::cast(map()->constructor());
1203 String* name = String::cast(constructor->shared()->name()); 1226 String* name = String::cast(constructor->shared()->name());
1204 if (name->length() > 0) return name; 1227 if (name->length() > 0) return name;
1205 String* inferred_name = constructor->shared()->inferred_name(); 1228 String* inferred_name = constructor->shared()->inferred_name();
1206 if (inferred_name->length() > 0) return inferred_name; 1229 if (inferred_name->length() > 0) return inferred_name;
1207 Object* proto = GetPrototype(); 1230 Object* proto = GetPrototype();
1208 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name(); 1231 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name();
1209 } 1232 }
1210 // If the constructor is not present, return "Object". 1233 // If the constructor is not present, return "Object".
1211 return Heap::Object_symbol(); 1234 return GetHeap()->Object_symbol();
1212 } 1235 }
1213 1236
1214 1237
1215 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, 1238 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map,
1216 String* name, 1239 String* name,
1217 Object* value) { 1240 Object* value) {
1218 int index = new_map->PropertyIndexFor(name); 1241 int index = new_map->PropertyIndexFor(name);
1219 if (map()->unused_property_fields() == 0) { 1242 if (map()->unused_property_fields() == 0) {
1220 ASSERT(map()->unused_property_fields() == 0); 1243 ASSERT(map()->unused_property_fields() == 0);
1221 int new_unused = new_map->unused_property_fields(); 1244 int new_unused = new_map->unused_property_fields();
1222 Object* values; 1245 Object* values;
1223 { MaybeObject* maybe_values = 1246 { MaybeObject* maybe_values =
1224 properties()->CopySize(properties()->length() + new_unused + 1); 1247 properties()->CopySize(properties()->length() + new_unused + 1);
1225 if (!maybe_values->ToObject(&values)) return maybe_values; 1248 if (!maybe_values->ToObject(&values)) return maybe_values;
1226 } 1249 }
1227 set_properties(FixedArray::cast(values)); 1250 set_properties(FixedArray::cast(values));
1228 } 1251 }
1229 set_map(new_map); 1252 set_map(new_map);
1230 return FastPropertyAtPut(index, value); 1253 return FastPropertyAtPut(index, value);
1231 } 1254 }
1232 1255
1233 1256
1234 MaybeObject* JSObject::AddFastProperty(String* name, 1257 MaybeObject* JSObject::AddFastProperty(String* name,
1235 Object* value, 1258 Object* value,
1236 PropertyAttributes attributes) { 1259 PropertyAttributes attributes) {
1237 ASSERT(!IsJSGlobalProxy()); 1260 ASSERT(!IsJSGlobalProxy());
1238 1261
1239 // Normalize the object if the name is an actual string (not the 1262 // Normalize the object if the name is an actual string (not the
1240 // hidden symbols) and is not a real identifier. 1263 // hidden symbols) and is not a real identifier.
1264 Isolate* isolate = GetHeap()->isolate();
1241 StringInputBuffer buffer(name); 1265 StringInputBuffer buffer(name);
1242 if (!ScannerConstants::IsIdentifier(&buffer) 1266 if (!isolate->scanner_constants()->IsIdentifier(&buffer)
1243 && name != Heap::hidden_symbol()) { 1267 && name != HEAP->hidden_symbol()) {
1244 Object* obj; 1268 Object* obj;
1245 { MaybeObject* maybe_obj = 1269 { MaybeObject* maybe_obj =
1246 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 1270 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1247 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1271 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1248 } 1272 }
1249 return AddSlowProperty(name, value, attributes); 1273 return AddSlowProperty(name, value, attributes);
1250 } 1274 }
1251 1275
1252 DescriptorArray* old_descriptors = map()->instance_descriptors(); 1276 DescriptorArray* old_descriptors = map()->instance_descriptors();
1253 // Compute the new index for new field. 1277 // Compute the new index for new field.
1254 int index = map()->NextFreePropertyIndex(); 1278 int index = map()->NextFreePropertyIndex();
1255 1279
1256 // Allocate new instance descriptors with (name, index) added 1280 // Allocate new instance descriptors with (name, index) added
1257 FieldDescriptor new_field(name, index, attributes); 1281 FieldDescriptor new_field(name, index, attributes);
1258 Object* new_descriptors; 1282 Object* new_descriptors;
1259 { MaybeObject* maybe_new_descriptors = 1283 { MaybeObject* maybe_new_descriptors =
1260 old_descriptors->CopyInsert(&new_field, REMOVE_TRANSITIONS); 1284 old_descriptors->CopyInsert(&new_field, REMOVE_TRANSITIONS);
1261 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { 1285 if (!maybe_new_descriptors->ToObject(&new_descriptors)) {
1262 return maybe_new_descriptors; 1286 return maybe_new_descriptors;
1263 } 1287 }
1264 } 1288 }
1265 1289
1266 // Only allow map transition if the object's map is NOT equal to the 1290 // Only allow map transition if the object's map is NOT equal to the
1267 // global object_function's map and there is not a transition for name. 1291 // global object_function's map and there is not a transition for name.
1268 bool allow_map_transition = 1292 bool allow_map_transition =
1269 !old_descriptors->Contains(name) && 1293 !old_descriptors->Contains(name) &&
1270 (Top::context()->global_context()->object_function()->map() != map()); 1294 (isolate->context()->global_context()->object_function()->
1295 map() != map());
1271 1296
1272 ASSERT(index < map()->inobject_properties() || 1297 ASSERT(index < map()->inobject_properties() ||
1273 (index - map()->inobject_properties()) < properties()->length() || 1298 (index - map()->inobject_properties()) < properties()->length() ||
1274 map()->unused_property_fields() == 0); 1299 map()->unused_property_fields() == 0);
1275 // Allocate a new map for the object. 1300 // Allocate a new map for the object.
1276 Object* r; 1301 Object* r;
1277 { MaybeObject* maybe_r = map()->CopyDropDescriptors(); 1302 { MaybeObject* maybe_r = map()->CopyDropDescriptors();
1278 if (!maybe_r->ToObject(&r)) return maybe_r; 1303 if (!maybe_r->ToObject(&r)) return maybe_r;
1279 } 1304 }
1280 Map* new_map = Map::cast(r); 1305 Map* new_map = Map::cast(r);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); 1339 new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));
1315 set_map(new_map); 1340 set_map(new_map);
1316 return FastPropertyAtPut(index, value); 1341 return FastPropertyAtPut(index, value);
1317 } 1342 }
1318 1343
1319 1344
1320 MaybeObject* JSObject::AddConstantFunctionProperty( 1345 MaybeObject* JSObject::AddConstantFunctionProperty(
1321 String* name, 1346 String* name,
1322 JSFunction* function, 1347 JSFunction* function,
1323 PropertyAttributes attributes) { 1348 PropertyAttributes attributes) {
1324 ASSERT(!Heap::InNewSpace(function)); 1349 Heap* heap = GetHeap();
1350 ASSERT(!heap->InNewSpace(function));
1325 1351
1326 // Allocate new instance descriptors with (name, function) added 1352 // Allocate new instance descriptors with (name, function) added
1327 ConstantFunctionDescriptor d(name, function, attributes); 1353 ConstantFunctionDescriptor d(name, function, attributes);
1328 Object* new_descriptors; 1354 Object* new_descriptors;
1329 { MaybeObject* maybe_new_descriptors = 1355 { MaybeObject* maybe_new_descriptors =
1330 map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS); 1356 map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS);
1331 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { 1357 if (!maybe_new_descriptors->ToObject(&new_descriptors)) {
1332 return maybe_new_descriptors; 1358 return maybe_new_descriptors;
1333 } 1359 }
1334 } 1360 }
1335 1361
1336 // Allocate a new map for the object. 1362 // Allocate a new map for the object.
1337 Object* new_map; 1363 Object* new_map;
1338 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); 1364 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors();
1339 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; 1365 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
1340 } 1366 }
1341 1367
1342 DescriptorArray* descriptors = DescriptorArray::cast(new_descriptors); 1368 DescriptorArray* descriptors = DescriptorArray::cast(new_descriptors);
1343 Map::cast(new_map)->set_instance_descriptors(descriptors); 1369 Map::cast(new_map)->set_instance_descriptors(descriptors);
1344 Map* old_map = map(); 1370 Map* old_map = map();
1345 set_map(Map::cast(new_map)); 1371 set_map(Map::cast(new_map));
1346 1372
1347 // If the old map is the global object map (from new Object()), 1373 // If the old map is the global object map (from new Object()),
1348 // then transitions are not added to it, so we are done. 1374 // then transitions are not added to it, so we are done.
1349 if (old_map == Top::context()->global_context()->object_function()->map()) { 1375 if (old_map == heap->isolate()->context()->global_context()->
1376 object_function()->map()) {
1350 return function; 1377 return function;
1351 } 1378 }
1352 1379
1353 // Do not add CONSTANT_TRANSITIONS to global objects 1380 // Do not add CONSTANT_TRANSITIONS to global objects
1354 if (IsGlobalObject()) { 1381 if (IsGlobalObject()) {
1355 return function; 1382 return function;
1356 } 1383 }
1357 1384
1358 // Add a CONSTANT_TRANSITION descriptor to the old map, 1385 // Add a CONSTANT_TRANSITION descriptor to the old map,
1359 // so future assignments to this property on other objects 1386 // so future assignments to this property on other objects
(...skipping 14 matching lines...) Expand all
1374 1401
1375 return function; 1402 return function;
1376 } 1403 }
1377 1404
1378 1405
1379 // Add property in slow mode 1406 // Add property in slow mode
1380 MaybeObject* JSObject::AddSlowProperty(String* name, 1407 MaybeObject* JSObject::AddSlowProperty(String* name,
1381 Object* value, 1408 Object* value,
1382 PropertyAttributes attributes) { 1409 PropertyAttributes attributes) {
1383 ASSERT(!HasFastProperties()); 1410 ASSERT(!HasFastProperties());
1411 Heap* heap = GetHeap();
1384 StringDictionary* dict = property_dictionary(); 1412 StringDictionary* dict = property_dictionary();
1385 Object* store_value = value; 1413 Object* store_value = value;
1386 if (IsGlobalObject()) { 1414 if (IsGlobalObject()) {
1387 // In case name is an orphaned property reuse the cell. 1415 // In case name is an orphaned property reuse the cell.
1388 int entry = dict->FindEntry(name); 1416 int entry = dict->FindEntry(name);
1389 if (entry != StringDictionary::kNotFound) { 1417 if (entry != StringDictionary::kNotFound) {
1390 store_value = dict->ValueAt(entry); 1418 store_value = dict->ValueAt(entry);
1391 JSGlobalPropertyCell::cast(store_value)->set_value(value); 1419 JSGlobalPropertyCell::cast(store_value)->set_value(value);
1392 // Assign an enumeration index to the property and update 1420 // Assign an enumeration index to the property and update
1393 // SetNextEnumerationIndex. 1421 // SetNextEnumerationIndex.
1394 int index = dict->NextEnumerationIndex(); 1422 int index = dict->NextEnumerationIndex();
1395 PropertyDetails details = PropertyDetails(attributes, NORMAL, index); 1423 PropertyDetails details = PropertyDetails(attributes, NORMAL, index);
1396 dict->SetNextEnumerationIndex(index + 1); 1424 dict->SetNextEnumerationIndex(index + 1);
1397 dict->SetEntry(entry, name, store_value, details); 1425 dict->SetEntry(entry, name, store_value, details);
1398 return value; 1426 return value;
1399 } 1427 }
1400 { MaybeObject* maybe_store_value = 1428 { MaybeObject* maybe_store_value =
1401 Heap::AllocateJSGlobalPropertyCell(value); 1429 heap->AllocateJSGlobalPropertyCell(value);
1402 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; 1430 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value;
1403 } 1431 }
1404 JSGlobalPropertyCell::cast(store_value)->set_value(value); 1432 JSGlobalPropertyCell::cast(store_value)->set_value(value);
1405 } 1433 }
1406 PropertyDetails details = PropertyDetails(attributes, NORMAL); 1434 PropertyDetails details = PropertyDetails(attributes, NORMAL);
1407 Object* result; 1435 Object* result;
1408 { MaybeObject* maybe_result = dict->Add(name, store_value, details); 1436 { MaybeObject* maybe_result = dict->Add(name, store_value, details);
1409 if (!maybe_result->ToObject(&result)) return maybe_result; 1437 if (!maybe_result->ToObject(&result)) return maybe_result;
1410 } 1438 }
1411 if (dict != result) set_properties(StringDictionary::cast(result)); 1439 if (dict != result) set_properties(StringDictionary::cast(result));
1412 return value; 1440 return value;
1413 } 1441 }
1414 1442
1415 1443
1416 MaybeObject* JSObject::AddProperty(String* name, 1444 MaybeObject* JSObject::AddProperty(String* name,
1417 Object* value, 1445 Object* value,
1418 PropertyAttributes attributes) { 1446 PropertyAttributes attributes) {
1419 ASSERT(!IsJSGlobalProxy()); 1447 ASSERT(!IsJSGlobalProxy());
1448 Heap* heap = GetHeap();
1420 if (!map()->is_extensible()) { 1449 if (!map()->is_extensible()) {
1421 Handle<Object> args[1] = {Handle<String>(name)}; 1450 Handle<Object> args[1] = {Handle<String>(name)};
1422 return Top::Throw(*Factory::NewTypeError("object_not_extensible", 1451 return heap->isolate()->Throw(
1423 HandleVector(args, 1))); 1452 *FACTORY->NewTypeError("object_not_extensible", HandleVector(args, 1)));
1424 } 1453 }
1425 if (HasFastProperties()) { 1454 if (HasFastProperties()) {
1426 // Ensure the descriptor array does not get too big. 1455 // Ensure the descriptor array does not get too big.
1427 if (map()->instance_descriptors()->number_of_descriptors() < 1456 if (map()->instance_descriptors()->number_of_descriptors() <
1428 DescriptorArray::kMaxNumberOfDescriptors) { 1457 DescriptorArray::kMaxNumberOfDescriptors) {
1429 if (value->IsJSFunction() && !Heap::InNewSpace(value)) { 1458 if (value->IsJSFunction() && !heap->InNewSpace(value)) {
1430 return AddConstantFunctionProperty(name, 1459 return AddConstantFunctionProperty(name,
1431 JSFunction::cast(value), 1460 JSFunction::cast(value),
1432 attributes); 1461 attributes);
1433 } else { 1462 } else {
1434 return AddFastProperty(name, value, attributes); 1463 return AddFastProperty(name, value, attributes);
1435 } 1464 }
1436 } else { 1465 } else {
1437 // Normalize the object to prevent very large instance descriptors. 1466 // Normalize the object to prevent very large instance descriptors.
1438 // This eliminates unwanted N^2 allocation and lookup behavior. 1467 // This eliminates unwanted N^2 allocation and lookup behavior.
1439 Object* obj; 1468 Object* obj;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1491 { MaybeObject* maybe_result = 1520 { MaybeObject* maybe_result =
1492 ConvertDescriptorToField(name, new_value, attributes); 1521 ConvertDescriptorToField(name, new_value, attributes);
1493 if (!maybe_result->ToObject(&result)) return maybe_result; 1522 if (!maybe_result->ToObject(&result)) return maybe_result;
1494 } 1523 }
1495 // If we get to this point we have succeeded - do not return failure 1524 // If we get to this point we have succeeded - do not return failure
1496 // after this point. Later stuff is optional. 1525 // after this point. Later stuff is optional.
1497 if (!HasFastProperties()) { 1526 if (!HasFastProperties()) {
1498 return result; 1527 return result;
1499 } 1528 }
1500 // Do not add transitions to the map of "new Object()". 1529 // Do not add transitions to the map of "new Object()".
1501 if (map() == Top::context()->global_context()->object_function()->map()) { 1530 if (map() == GetHeap()->isolate()->context()->global_context()->
1531 object_function()->map()) {
1502 return result; 1532 return result;
1503 } 1533 }
1504 1534
1505 MapTransitionDescriptor transition(name, 1535 MapTransitionDescriptor transition(name,
1506 map(), 1536 map(),
1507 attributes); 1537 attributes);
1508 Object* new_descriptors; 1538 Object* new_descriptors;
1509 { MaybeObject* maybe_new_descriptors = old_map->instance_descriptors()-> 1539 { MaybeObject* maybe_new_descriptors = old_map->instance_descriptors()->
1510 CopyInsert(&transition, KEEP_TRANSITIONS); 1540 CopyInsert(&transition, KEEP_TRANSITIONS);
1511 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { 1541 if (!maybe_new_descriptors->ToObject(&new_descriptors)) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1578 return FastPropertyAtPut(index, new_value); 1608 return FastPropertyAtPut(index, new_value);
1579 } 1609 }
1580 1610
1581 1611
1582 1612
1583 MaybeObject* JSObject::SetPropertyWithInterceptor( 1613 MaybeObject* JSObject::SetPropertyWithInterceptor(
1584 String* name, 1614 String* name,
1585 Object* value, 1615 Object* value,
1586 PropertyAttributes attributes, 1616 PropertyAttributes attributes,
1587 StrictModeFlag strict_mode) { 1617 StrictModeFlag strict_mode) {
1588 HandleScope scope; 1618 Isolate* isolate = GetIsolate();
1619 HandleScope scope(isolate);
1589 Handle<JSObject> this_handle(this); 1620 Handle<JSObject> this_handle(this);
1590 Handle<String> name_handle(name); 1621 Handle<String> name_handle(name);
1591 Handle<Object> value_handle(value); 1622 Handle<Object> value_handle(value, isolate);
1592 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); 1623 Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
1593 if (!interceptor->setter()->IsUndefined()) { 1624 if (!interceptor->setter()->IsUndefined()) {
1594 LOG(ApiNamedPropertyAccess("interceptor-named-set", this, name)); 1625 LOG(isolate, ApiNamedPropertyAccess("interceptor-named-set", this, name));
1595 CustomArguments args(interceptor->data(), this, this); 1626 CustomArguments args(isolate, interceptor->data(), this, this);
1596 v8::AccessorInfo info(args.end()); 1627 v8::AccessorInfo info(args.end());
1597 v8::NamedPropertySetter setter = 1628 v8::NamedPropertySetter setter =
1598 v8::ToCData<v8::NamedPropertySetter>(interceptor->setter()); 1629 v8::ToCData<v8::NamedPropertySetter>(interceptor->setter());
1599 v8::Handle<v8::Value> result; 1630 v8::Handle<v8::Value> result;
1600 { 1631 {
1601 // Leaving JavaScript. 1632 // Leaving JavaScript.
1602 VMState state(EXTERNAL); 1633 VMState state(isolate, EXTERNAL);
1603 Handle<Object> value_unhole(value->IsTheHole() ? 1634 Handle<Object> value_unhole(value->IsTheHole() ?
1604 Heap::undefined_value() : 1635 isolate->heap()->undefined_value() :
1605 value); 1636 value,
1637 isolate);
1606 result = setter(v8::Utils::ToLocal(name_handle), 1638 result = setter(v8::Utils::ToLocal(name_handle),
1607 v8::Utils::ToLocal(value_unhole), 1639 v8::Utils::ToLocal(value_unhole),
1608 info); 1640 info);
1609 } 1641 }
1610 RETURN_IF_SCHEDULED_EXCEPTION(); 1642 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1611 if (!result.IsEmpty()) return *value_handle; 1643 if (!result.IsEmpty()) return *value_handle;
1612 } 1644 }
1613 MaybeObject* raw_result = 1645 MaybeObject* raw_result =
1614 this_handle->SetPropertyPostInterceptor(*name_handle, 1646 this_handle->SetPropertyPostInterceptor(*name_handle,
1615 *value_handle, 1647 *value_handle,
1616 attributes, 1648 attributes,
1617 strict_mode); 1649 strict_mode);
1618 RETURN_IF_SCHEDULED_EXCEPTION(); 1650 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1619 return raw_result; 1651 return raw_result;
1620 } 1652 }
1621 1653
1622 1654
1623 MaybeObject* JSObject::SetProperty(String* name, 1655 MaybeObject* JSObject::SetProperty(String* name,
1624 Object* value, 1656 Object* value,
1625 PropertyAttributes attributes, 1657 PropertyAttributes attributes,
1626 StrictModeFlag strict_mode) { 1658 StrictModeFlag strict_mode) {
1627 LookupResult result; 1659 LookupResult result;
1628 LocalLookup(name, &result); 1660 LocalLookup(name, &result);
1629 return SetProperty(&result, name, value, attributes, strict_mode); 1661 return SetProperty(&result, name, value, attributes, strict_mode);
1630 } 1662 }
1631 1663
1632 1664
1633 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, 1665 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure,
1634 String* name, 1666 String* name,
1635 Object* value, 1667 Object* value,
1636 JSObject* holder) { 1668 JSObject* holder) {
1637 HandleScope scope; 1669 Isolate* isolate = GetIsolate();
1670 HandleScope scope(isolate);
1638 1671
1639 // We should never get here to initialize a const with the hole 1672 // We should never get here to initialize a const with the hole
1640 // value since a const declaration would conflict with the setter. 1673 // value since a const declaration would conflict with the setter.
1641 ASSERT(!value->IsTheHole()); 1674 ASSERT(!value->IsTheHole());
1642 Handle<Object> value_handle(value); 1675 Handle<Object> value_handle(value, isolate);
1643 1676
1644 // To accommodate both the old and the new api we switch on the 1677 // To accommodate both the old and the new api we switch on the
1645 // data structure used to store the callbacks. Eventually proxy 1678 // data structure used to store the callbacks. Eventually proxy
1646 // callbacks should be phased out. 1679 // callbacks should be phased out.
1647 if (structure->IsProxy()) { 1680 if (structure->IsProxy()) {
1648 AccessorDescriptor* callback = 1681 AccessorDescriptor* callback =
1649 reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy()); 1682 reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy());
1650 MaybeObject* obj = (callback->setter)(this, value, callback->data); 1683 MaybeObject* obj = (callback->setter)(this, value, callback->data);
1651 RETURN_IF_SCHEDULED_EXCEPTION(); 1684 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1652 if (obj->IsFailure()) return obj; 1685 if (obj->IsFailure()) return obj;
1653 return *value_handle; 1686 return *value_handle;
1654 } 1687 }
1655 1688
1656 if (structure->IsAccessorInfo()) { 1689 if (structure->IsAccessorInfo()) {
1657 // api style callbacks 1690 // api style callbacks
1658 AccessorInfo* data = AccessorInfo::cast(structure); 1691 AccessorInfo* data = AccessorInfo::cast(structure);
1659 Object* call_obj = data->setter(); 1692 Object* call_obj = data->setter();
1660 v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj); 1693 v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj);
1661 if (call_fun == NULL) return value; 1694 if (call_fun == NULL) return value;
1662 Handle<String> key(name); 1695 Handle<String> key(name);
1663 LOG(ApiNamedPropertyAccess("store", this, name)); 1696 LOG(isolate, ApiNamedPropertyAccess("store", this, name));
1664 CustomArguments args(data->data(), this, JSObject::cast(holder)); 1697 CustomArguments args(isolate, data->data(), this, JSObject::cast(holder));
1665 v8::AccessorInfo info(args.end()); 1698 v8::AccessorInfo info(args.end());
1666 { 1699 {
1667 // Leaving JavaScript. 1700 // Leaving JavaScript.
1668 VMState state(EXTERNAL); 1701 VMState state(isolate, EXTERNAL);
1669 call_fun(v8::Utils::ToLocal(key), 1702 call_fun(v8::Utils::ToLocal(key),
1670 v8::Utils::ToLocal(value_handle), 1703 v8::Utils::ToLocal(value_handle),
1671 info); 1704 info);
1672 } 1705 }
1673 RETURN_IF_SCHEDULED_EXCEPTION(); 1706 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
1674 return *value_handle; 1707 return *value_handle;
1675 } 1708 }
1676 1709
1677 if (structure->IsFixedArray()) { 1710 if (structure->IsFixedArray()) {
1678 Object* setter = FixedArray::cast(structure)->get(kSetterIndex); 1711 Object* setter = FixedArray::cast(structure)->get(kSetterIndex);
1679 if (setter->IsJSFunction()) { 1712 if (setter->IsJSFunction()) {
1680 return SetPropertyWithDefinedSetter(JSFunction::cast(setter), value); 1713 return SetPropertyWithDefinedSetter(JSFunction::cast(setter), value);
1681 } else { 1714 } else {
1682 Handle<String> key(name); 1715 Handle<String> key(name);
1683 Handle<Object> holder_handle(holder); 1716 Handle<Object> holder_handle(holder, isolate);
1684 Handle<Object> args[2] = { key, holder_handle }; 1717 Handle<Object> args[2] = { key, holder_handle };
1685 return Top::Throw(*Factory::NewTypeError("no_setter_in_callback", 1718 return isolate->Throw(
1686 HandleVector(args, 2))); 1719 *isolate->factory()->NewTypeError("no_setter_in_callback",
1720 HandleVector(args, 2)));
1687 } 1721 }
1688 } 1722 }
1689 1723
1690 UNREACHABLE(); 1724 UNREACHABLE();
1691 return NULL; 1725 return NULL;
1692 } 1726 }
1693 1727
1694 1728
1695 MaybeObject* JSObject::SetPropertyWithDefinedSetter(JSFunction* setter, 1729 MaybeObject* JSObject::SetPropertyWithDefinedSetter(JSFunction* setter,
1696 Object* value) { 1730 Object* value) {
1697 Handle<Object> value_handle(value); 1731 Isolate* isolate = GetIsolate();
1698 Handle<JSFunction> fun(JSFunction::cast(setter)); 1732 Handle<Object> value_handle(value, isolate);
1699 Handle<JSObject> self(this); 1733 Handle<JSFunction> fun(JSFunction::cast(setter), isolate);
1734 Handle<JSObject> self(this, isolate);
1700 #ifdef ENABLE_DEBUGGER_SUPPORT 1735 #ifdef ENABLE_DEBUGGER_SUPPORT
1736 Debug* debug = isolate->debug();
1701 // Handle stepping into a setter if step into is active. 1737 // Handle stepping into a setter if step into is active.
1702 if (Debug::StepInActive()) { 1738 if (debug->StepInActive()) {
1703 Debug::HandleStepIn(fun, Handle<Object>::null(), 0, false); 1739 debug->HandleStepIn(fun, Handle<Object>::null(), 0, false);
1704 } 1740 }
1705 #endif 1741 #endif
1706 bool has_pending_exception; 1742 bool has_pending_exception;
1707 Object** argv[] = { value_handle.location() }; 1743 Object** argv[] = { value_handle.location() };
1708 Execution::Call(fun, self, 1, argv, &has_pending_exception); 1744 Execution::Call(fun, self, 1, argv, &has_pending_exception);
1709 // Check for pending exception and return the result. 1745 // Check for pending exception and return the result.
1710 if (has_pending_exception) return Failure::Exception(); 1746 if (has_pending_exception) return Failure::Exception();
1711 return *value_handle; 1747 return *value_handle;
1712 } 1748 }
1713 1749
1714 1750
1715 void JSObject::LookupCallbackSetterInPrototypes(String* name, 1751 void JSObject::LookupCallbackSetterInPrototypes(String* name,
1716 LookupResult* result) { 1752 LookupResult* result) {
1753 Heap* heap = GetHeap();
1717 for (Object* pt = GetPrototype(); 1754 for (Object* pt = GetPrototype();
1718 pt != Heap::null_value(); 1755 pt != heap->null_value();
1719 pt = pt->GetPrototype()) { 1756 pt = pt->GetPrototype()) {
1720 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); 1757 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
1721 if (result->IsProperty()) { 1758 if (result->IsProperty()) {
1722 if (result->IsReadOnly()) { 1759 if (result->IsReadOnly()) {
1723 result->NotFound(); 1760 result->NotFound();
1724 return; 1761 return;
1725 } 1762 }
1726 if (result->type() == CALLBACKS) { 1763 if (result->type() == CALLBACKS) {
1727 return; 1764 return;
1728 } 1765 }
1729 } 1766 }
1730 } 1767 }
1731 result->NotFound(); 1768 result->NotFound();
1732 } 1769 }
1733 1770
1734 1771
1735 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(uint32_t index, 1772 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(uint32_t index,
1736 Object* value, 1773 Object* value,
1737 bool* found) { 1774 bool* found) {
1775 Heap* heap = GetHeap();
1738 for (Object* pt = GetPrototype(); 1776 for (Object* pt = GetPrototype();
1739 pt != Heap::null_value(); 1777 pt != heap->null_value();
1740 pt = pt->GetPrototype()) { 1778 pt = pt->GetPrototype()) {
1741 if (!JSObject::cast(pt)->HasDictionaryElements()) { 1779 if (!JSObject::cast(pt)->HasDictionaryElements()) {
1742 continue; 1780 continue;
1743 } 1781 }
1744 NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary(); 1782 NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary();
1745 int entry = dictionary->FindEntry(index); 1783 int entry = dictionary->FindEntry(index);
1746 if (entry != NumberDictionary::kNotFound) { 1784 if (entry != NumberDictionary::kNotFound) {
1747 PropertyDetails details = dictionary->DetailsAt(entry); 1785 PropertyDetails details = dictionary->DetailsAt(entry);
1748 if (details.type() == CALLBACKS) { 1786 if (details.type() == CALLBACKS) {
1749 *found = true; 1787 *found = true;
1750 return SetElementWithCallback( 1788 return SetElementWithCallback(
1751 dictionary->ValueAt(entry), index, value, JSObject::cast(pt)); 1789 dictionary->ValueAt(entry), index, value, JSObject::cast(pt));
1752 } 1790 }
1753 } 1791 }
1754 } 1792 }
1755 *found = false; 1793 *found = false;
1756 return Heap::the_hole_value(); 1794 return heap->the_hole_value();
1757 } 1795 }
1758 1796
1759 1797
1760 void JSObject::LookupInDescriptor(String* name, LookupResult* result) { 1798 void JSObject::LookupInDescriptor(String* name, LookupResult* result) {
1761 DescriptorArray* descriptors = map()->instance_descriptors(); 1799 DescriptorArray* descriptors = map()->instance_descriptors();
1762 int number = descriptors->SearchWithCache(name); 1800 int number = descriptors->SearchWithCache(name);
1763 if (number != DescriptorArray::kNotFound) { 1801 if (number != DescriptorArray::kNotFound) {
1764 result->DescriptorResult(this, descriptors->GetDetails(number), number); 1802 result->DescriptorResult(this, descriptors->GetDetails(number), number);
1765 } else { 1803 } else {
1766 result->NotFound(); 1804 result->NotFound();
1767 } 1805 }
1768 } 1806 }
1769 1807
1770 1808
1771 void Map::LookupInDescriptors(JSObject* holder, 1809 void Map::LookupInDescriptors(JSObject* holder,
1772 String* name, 1810 String* name,
1773 LookupResult* result) { 1811 LookupResult* result) {
1774 DescriptorArray* descriptors = instance_descriptors(); 1812 DescriptorArray* descriptors = instance_descriptors();
1775 int number = DescriptorLookupCache::Lookup(descriptors, name); 1813 DescriptorLookupCache* cache = heap()->isolate()->descriptor_lookup_cache();
1814 int number = cache->Lookup(descriptors, name);
1776 if (number == DescriptorLookupCache::kAbsent) { 1815 if (number == DescriptorLookupCache::kAbsent) {
1777 number = descriptors->Search(name); 1816 number = descriptors->Search(name);
1778 DescriptorLookupCache::Update(descriptors, name, number); 1817 cache->Update(descriptors, name, number);
1779 } 1818 }
1780 if (number != DescriptorArray::kNotFound) { 1819 if (number != DescriptorArray::kNotFound) {
1781 result->DescriptorResult(holder, descriptors->GetDetails(number), number); 1820 result->DescriptorResult(holder, descriptors->GetDetails(number), number);
1782 } else { 1821 } else {
1783 result->NotFound(); 1822 result->NotFound();
1784 } 1823 }
1785 } 1824 }
1786 1825
1787 1826
1788 void JSObject::LocalLookupRealNamedProperty(String* name, 1827 void JSObject::LocalLookupRealNamedProperty(String* name,
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1836 void JSObject::LookupRealNamedProperty(String* name, LookupResult* result) { 1875 void JSObject::LookupRealNamedProperty(String* name, LookupResult* result) {
1837 LocalLookupRealNamedProperty(name, result); 1876 LocalLookupRealNamedProperty(name, result);
1838 if (result->IsProperty()) return; 1877 if (result->IsProperty()) return;
1839 1878
1840 LookupRealNamedPropertyInPrototypes(name, result); 1879 LookupRealNamedPropertyInPrototypes(name, result);
1841 } 1880 }
1842 1881
1843 1882
1844 void JSObject::LookupRealNamedPropertyInPrototypes(String* name, 1883 void JSObject::LookupRealNamedPropertyInPrototypes(String* name,
1845 LookupResult* result) { 1884 LookupResult* result) {
1885 Heap* heap = GetHeap();
1846 for (Object* pt = GetPrototype(); 1886 for (Object* pt = GetPrototype();
1847 pt != Heap::null_value(); 1887 pt != heap->null_value();
1848 pt = JSObject::cast(pt)->GetPrototype()) { 1888 pt = JSObject::cast(pt)->GetPrototype()) {
1849 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); 1889 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
1850 if (result->IsProperty() && (result->type() != INTERCEPTOR)) return; 1890 if (result->IsProperty() && (result->type() != INTERCEPTOR)) return;
1851 } 1891 }
1852 result->NotFound(); 1892 result->NotFound();
1853 } 1893 }
1854 1894
1855 1895
1856 // We only need to deal with CALLBACKS and INTERCEPTORS 1896 // We only need to deal with CALLBACKS and INTERCEPTORS
1857 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result, 1897 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result,
1858 String* name, 1898 String* name,
1859 Object* value, 1899 Object* value,
1860 bool check_prototype) { 1900 bool check_prototype) {
1901 Heap* heap = GetHeap();
1861 if (check_prototype && !result->IsProperty()) { 1902 if (check_prototype && !result->IsProperty()) {
1862 LookupCallbackSetterInPrototypes(name, result); 1903 LookupCallbackSetterInPrototypes(name, result);
1863 } 1904 }
1864 1905
1865 if (result->IsProperty()) { 1906 if (result->IsProperty()) {
1866 if (!result->IsReadOnly()) { 1907 if (!result->IsReadOnly()) {
1867 switch (result->type()) { 1908 switch (result->type()) {
1868 case CALLBACKS: { 1909 case CALLBACKS: {
1869 Object* obj = result->GetCallbackObject(); 1910 Object* obj = result->GetCallbackObject();
1870 if (obj->IsAccessorInfo()) { 1911 if (obj->IsAccessorInfo()) {
(...skipping 20 matching lines...) Expand all
1891 } 1932 }
1892 default: { 1933 default: {
1893 break; 1934 break;
1894 } 1935 }
1895 } 1936 }
1896 } 1937 }
1897 } 1938 }
1898 1939
1899 HandleScope scope; 1940 HandleScope scope;
1900 Handle<Object> value_handle(value); 1941 Handle<Object> value_handle(value);
1901 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); 1942 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET);
1902 return *value_handle; 1943 return *value_handle;
1903 } 1944 }
1904 1945
1905 1946
1906 MaybeObject* JSObject::SetProperty(LookupResult* result, 1947 MaybeObject* JSObject::SetProperty(LookupResult* result,
1907 String* name, 1948 String* name,
1908 Object* value, 1949 Object* value,
1909 PropertyAttributes attributes, 1950 PropertyAttributes attributes,
1910 StrictModeFlag strict_mode) { 1951 StrictModeFlag strict_mode) {
1952 Heap* heap = GetHeap();
1911 // Make sure that the top context does not change when doing callbacks or 1953 // Make sure that the top context does not change when doing callbacks or
1912 // interceptor calls. 1954 // interceptor calls.
1913 AssertNoContextChange ncc; 1955 AssertNoContextChange ncc;
1914 1956
1915 // Optimization for 2-byte strings often used as keys in a decompression 1957 // Optimization for 2-byte strings often used as keys in a decompression
1916 // dictionary. We make these short keys into symbols to avoid constantly 1958 // dictionary. We make these short keys into symbols to avoid constantly
1917 // reallocating them. 1959 // reallocating them.
1918 if (!name->IsSymbol() && name->length() <= 2) { 1960 if (!name->IsSymbol() && name->length() <= 2) {
1919 Object* symbol_version; 1961 Object* symbol_version;
1920 { MaybeObject* maybe_symbol_version = Heap::LookupSymbol(name); 1962 { MaybeObject* maybe_symbol_version = heap->LookupSymbol(name);
1921 if (maybe_symbol_version->ToObject(&symbol_version)) { 1963 if (maybe_symbol_version->ToObject(&symbol_version)) {
1922 name = String::cast(symbol_version); 1964 name = String::cast(symbol_version);
1923 } 1965 }
1924 } 1966 }
1925 } 1967 }
1926 1968
1927 // Check access rights if needed. 1969 // Check access rights if needed.
1928 if (IsAccessCheckNeeded() 1970 if (IsAccessCheckNeeded()
1929 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { 1971 && !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) {
1930 return SetPropertyWithFailedAccessCheck(result, name, value, true); 1972 return SetPropertyWithFailedAccessCheck(result, name, value, true);
1931 } 1973 }
1932 1974
1933 if (IsJSGlobalProxy()) { 1975 if (IsJSGlobalProxy()) {
1934 Object* proto = GetPrototype(); 1976 Object* proto = GetPrototype();
1935 if (proto->IsNull()) return value; 1977 if (proto->IsNull()) return value;
1936 ASSERT(proto->IsJSGlobalObject()); 1978 ASSERT(proto->IsJSGlobalObject());
1937 return JSObject::cast(proto)->SetProperty( 1979 return JSObject::cast(proto)->SetProperty(
1938 result, name, value, attributes, strict_mode); 1980 result, name, value, attributes, strict_mode);
1939 } 1981 }
(...skipping 13 matching lines...) Expand all
1953 if (!result->IsFound()) { 1995 if (!result->IsFound()) {
1954 // Neither properties nor transitions found. 1996 // Neither properties nor transitions found.
1955 return AddProperty(name, value, attributes); 1997 return AddProperty(name, value, attributes);
1956 } 1998 }
1957 if (result->IsReadOnly() && result->IsProperty()) { 1999 if (result->IsReadOnly() && result->IsProperty()) {
1958 if (strict_mode == kStrictMode) { 2000 if (strict_mode == kStrictMode) {
1959 HandleScope scope; 2001 HandleScope scope;
1960 Handle<String> key(name); 2002 Handle<String> key(name);
1961 Handle<Object> holder(this); 2003 Handle<Object> holder(this);
1962 Handle<Object> args[2] = { key, holder }; 2004 Handle<Object> args[2] = { key, holder };
1963 return Top::Throw(*Factory::NewTypeError("strict_read_only_property", 2005 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError(
1964 HandleVector(args, 2))); 2006 "strict_read_only_property", HandleVector(args, 2)));
1965 } else { 2007 } else {
1966 return value; 2008 return value;
1967 } 2009 }
1968 } 2010 }
1969 // This is a real property that is not read-only, or it is a 2011 // This is a real property that is not read-only, or it is a
1970 // transition or null descriptor and there are no setters in the prototypes. 2012 // transition or null descriptor and there are no setters in the prototypes.
1971 switch (result->type()) { 2013 switch (result->type()) {
1972 case NORMAL: 2014 case NORMAL:
1973 return SetNormalizedProperty(result, value); 2015 return SetNormalizedProperty(result, value);
1974 case FIELD: 2016 case FIELD:
(...skipping 22 matching lines...) Expand all
1997 case CONSTANT_TRANSITION: { 2039 case CONSTANT_TRANSITION: {
1998 // If the same constant function is being added we can simply 2040 // If the same constant function is being added we can simply
1999 // transition to the target map. 2041 // transition to the target map.
2000 Map* target_map = result->GetTransitionMap(); 2042 Map* target_map = result->GetTransitionMap();
2001 DescriptorArray* target_descriptors = target_map->instance_descriptors(); 2043 DescriptorArray* target_descriptors = target_map->instance_descriptors();
2002 int number = target_descriptors->SearchWithCache(name); 2044 int number = target_descriptors->SearchWithCache(name);
2003 ASSERT(number != DescriptorArray::kNotFound); 2045 ASSERT(number != DescriptorArray::kNotFound);
2004 ASSERT(target_descriptors->GetType(number) == CONSTANT_FUNCTION); 2046 ASSERT(target_descriptors->GetType(number) == CONSTANT_FUNCTION);
2005 JSFunction* function = 2047 JSFunction* function =
2006 JSFunction::cast(target_descriptors->GetValue(number)); 2048 JSFunction::cast(target_descriptors->GetValue(number));
2007 ASSERT(!Heap::InNewSpace(function)); 2049 ASSERT(!HEAP->InNewSpace(function));
2008 if (value == function) { 2050 if (value == function) {
2009 set_map(target_map); 2051 set_map(target_map);
2010 return value; 2052 return value;
2011 } 2053 }
2012 // Otherwise, replace with a MAP_TRANSITION to a new map with a 2054 // Otherwise, replace with a MAP_TRANSITION to a new map with a
2013 // FIELD, even if the value is a constant function. 2055 // FIELD, even if the value is a constant function.
2014 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); 2056 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
2015 } 2057 }
2016 case NULL_DESCRIPTOR: 2058 case NULL_DESCRIPTOR:
2017 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); 2059 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
2018 default: 2060 default:
2019 UNREACHABLE(); 2061 UNREACHABLE();
2020 } 2062 }
2021 UNREACHABLE(); 2063 UNREACHABLE();
2022 return value; 2064 return value;
2023 } 2065 }
2024 2066
2025 2067
2026 // Set a real local property, even if it is READ_ONLY. If the property is not 2068 // Set a real local property, even if it is READ_ONLY. If the property is not
2027 // present, add it with attributes NONE. This code is an exact clone of 2069 // present, add it with attributes NONE. This code is an exact clone of
2028 // SetProperty, with the check for IsReadOnly and the check for a 2070 // SetProperty, with the check for IsReadOnly and the check for a
2029 // callback setter removed. The two lines looking up the LookupResult 2071 // callback setter removed. The two lines looking up the LookupResult
2030 // result are also added. If one of the functions is changed, the other 2072 // result are also added. If one of the functions is changed, the other
2031 // should be. 2073 // should be.
2032 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( 2074 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
2033 String* name, 2075 String* name,
2034 Object* value, 2076 Object* value,
2035 PropertyAttributes attributes) { 2077 PropertyAttributes attributes) {
2078 Heap* heap = GetHeap();
2079
2036 // Make sure that the top context does not change when doing callbacks or 2080 // Make sure that the top context does not change when doing callbacks or
2037 // interceptor calls. 2081 // interceptor calls.
2038 AssertNoContextChange ncc; 2082 AssertNoContextChange ncc;
2039 LookupResult result; 2083 LookupResult result;
2040 LocalLookup(name, &result); 2084 LocalLookup(name, &result);
2041 // Check access rights if needed. 2085 // Check access rights if needed.
2042 if (IsAccessCheckNeeded() 2086 if (IsAccessCheckNeeded()
2043 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { 2087 && !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) {
2044 return SetPropertyWithFailedAccessCheck(&result, name, value, false); 2088 return SetPropertyWithFailedAccessCheck(&result, name, value, false);
2045 } 2089 }
2046 2090
2047 if (IsJSGlobalProxy()) { 2091 if (IsJSGlobalProxy()) {
2048 Object* proto = GetPrototype(); 2092 Object* proto = GetPrototype();
2049 if (proto->IsNull()) return value; 2093 if (proto->IsNull()) return value;
2050 ASSERT(proto->IsJSGlobalObject()); 2094 ASSERT(proto->IsJSGlobalObject());
2051 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( 2095 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes(
2052 name, 2096 name,
2053 value, 2097 value,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2105 String* name, 2149 String* name,
2106 bool continue_search) { 2150 bool continue_search) {
2107 // Check local property, ignore interceptor. 2151 // Check local property, ignore interceptor.
2108 LookupResult result; 2152 LookupResult result;
2109 LocalLookupRealNamedProperty(name, &result); 2153 LocalLookupRealNamedProperty(name, &result);
2110 if (result.IsProperty()) return result.GetAttributes(); 2154 if (result.IsProperty()) return result.GetAttributes();
2111 2155
2112 if (continue_search) { 2156 if (continue_search) {
2113 // Continue searching via the prototype chain. 2157 // Continue searching via the prototype chain.
2114 Object* pt = GetPrototype(); 2158 Object* pt = GetPrototype();
2115 if (pt != Heap::null_value()) { 2159 if (!pt->IsNull()) {
2116 return JSObject::cast(pt)-> 2160 return JSObject::cast(pt)->
2117 GetPropertyAttributeWithReceiver(receiver, name); 2161 GetPropertyAttributeWithReceiver(receiver, name);
2118 } 2162 }
2119 } 2163 }
2120 return ABSENT; 2164 return ABSENT;
2121 } 2165 }
2122 2166
2123 2167
2124 PropertyAttributes JSObject::GetPropertyAttributeWithInterceptor( 2168 PropertyAttributes JSObject::GetPropertyAttributeWithInterceptor(
2125 JSObject* receiver, 2169 JSObject* receiver,
2126 String* name, 2170 String* name,
2127 bool continue_search) { 2171 bool continue_search) {
2172 Isolate* isolate = GetIsolate();
2173
2128 // Make sure that the top context does not change when doing 2174 // Make sure that the top context does not change when doing
2129 // callbacks or interceptor calls. 2175 // callbacks or interceptor calls.
2130 AssertNoContextChange ncc; 2176 AssertNoContextChange ncc;
2131 2177
2132 HandleScope scope; 2178 HandleScope scope(isolate);
2133 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); 2179 Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
2134 Handle<JSObject> receiver_handle(receiver); 2180 Handle<JSObject> receiver_handle(receiver);
2135 Handle<JSObject> holder_handle(this); 2181 Handle<JSObject> holder_handle(this);
2136 Handle<String> name_handle(name); 2182 Handle<String> name_handle(name);
2137 CustomArguments args(interceptor->data(), receiver, this); 2183 CustomArguments args(isolate, interceptor->data(), receiver, this);
2138 v8::AccessorInfo info(args.end()); 2184 v8::AccessorInfo info(args.end());
2139 if (!interceptor->query()->IsUndefined()) { 2185 if (!interceptor->query()->IsUndefined()) {
2140 v8::NamedPropertyQuery query = 2186 v8::NamedPropertyQuery query =
2141 v8::ToCData<v8::NamedPropertyQuery>(interceptor->query()); 2187 v8::ToCData<v8::NamedPropertyQuery>(interceptor->query());
2142 LOG(ApiNamedPropertyAccess("interceptor-named-has", *holder_handle, name)); 2188 LOG(isolate,
2189 ApiNamedPropertyAccess("interceptor-named-has", *holder_handle, name));
2143 v8::Handle<v8::Integer> result; 2190 v8::Handle<v8::Integer> result;
2144 { 2191 {
2145 // Leaving JavaScript. 2192 // Leaving JavaScript.
2146 VMState state(EXTERNAL); 2193 VMState state(isolate, EXTERNAL);
2147 result = query(v8::Utils::ToLocal(name_handle), info); 2194 result = query(v8::Utils::ToLocal(name_handle), info);
2148 } 2195 }
2149 if (!result.IsEmpty()) { 2196 if (!result.IsEmpty()) {
2150 ASSERT(result->IsInt32()); 2197 ASSERT(result->IsInt32());
2151 return static_cast<PropertyAttributes>(result->Int32Value()); 2198 return static_cast<PropertyAttributes>(result->Int32Value());
2152 } 2199 }
2153 } else if (!interceptor->getter()->IsUndefined()) { 2200 } else if (!interceptor->getter()->IsUndefined()) {
2154 v8::NamedPropertyGetter getter = 2201 v8::NamedPropertyGetter getter =
2155 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter()); 2202 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter());
2156 LOG(ApiNamedPropertyAccess("interceptor-named-get-has", this, name)); 2203 LOG(isolate,
2204 ApiNamedPropertyAccess("interceptor-named-get-has", this, name));
2157 v8::Handle<v8::Value> result; 2205 v8::Handle<v8::Value> result;
2158 { 2206 {
2159 // Leaving JavaScript. 2207 // Leaving JavaScript.
2160 VMState state(EXTERNAL); 2208 VMState state(isolate, EXTERNAL);
2161 result = getter(v8::Utils::ToLocal(name_handle), info); 2209 result = getter(v8::Utils::ToLocal(name_handle), info);
2162 } 2210 }
2163 if (!result.IsEmpty()) return DONT_ENUM; 2211 if (!result.IsEmpty()) return DONT_ENUM;
2164 } 2212 }
2165 return holder_handle->GetPropertyAttributePostInterceptor(*receiver_handle, 2213 return holder_handle->GetPropertyAttributePostInterceptor(*receiver_handle,
2166 *name_handle, 2214 *name_handle,
2167 continue_search); 2215 continue_search);
2168 } 2216 }
2169 2217
2170 2218
2171 PropertyAttributes JSObject::GetPropertyAttributeWithReceiver( 2219 PropertyAttributes JSObject::GetPropertyAttributeWithReceiver(
2172 JSObject* receiver, 2220 JSObject* receiver,
2173 String* key) { 2221 String* key) {
2174 uint32_t index = 0; 2222 uint32_t index = 0;
2175 if (key->AsArrayIndex(&index)) { 2223 if (key->AsArrayIndex(&index)) {
2176 if (HasElementWithReceiver(receiver, index)) return NONE; 2224 if (HasElementWithReceiver(receiver, index)) return NONE;
2177 return ABSENT; 2225 return ABSENT;
2178 } 2226 }
2179 // Named property. 2227 // Named property.
2180 LookupResult result; 2228 LookupResult result;
2181 Lookup(key, &result); 2229 Lookup(key, &result);
2182 return GetPropertyAttribute(receiver, &result, key, true); 2230 return GetPropertyAttribute(receiver, &result, key, true);
2183 } 2231 }
2184 2232
2185 2233
2186 PropertyAttributes JSObject::GetPropertyAttribute(JSObject* receiver, 2234 PropertyAttributes JSObject::GetPropertyAttribute(JSObject* receiver,
2187 LookupResult* result, 2235 LookupResult* result,
2188 String* name, 2236 String* name,
2189 bool continue_search) { 2237 bool continue_search) {
2238 Heap* heap = GetHeap();
2190 // Check access rights if needed. 2239 // Check access rights if needed.
2191 if (IsAccessCheckNeeded() && 2240 if (IsAccessCheckNeeded() &&
2192 !Top::MayNamedAccess(this, name, v8::ACCESS_HAS)) { 2241 !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) {
2193 return GetPropertyAttributeWithFailedAccessCheck(receiver, 2242 return GetPropertyAttributeWithFailedAccessCheck(receiver,
2194 result, 2243 result,
2195 name, 2244 name,
2196 continue_search); 2245 continue_search);
2197 } 2246 }
2198 if (result->IsProperty()) { 2247 if (result->IsProperty()) {
2199 switch (result->type()) { 2248 switch (result->type()) {
2200 case NORMAL: // fall through 2249 case NORMAL: // fall through
2201 case FIELD: 2250 case FIELD:
2202 case CONSTANT_FUNCTION: 2251 case CONSTANT_FUNCTION:
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2248 } 2297 }
2249 #endif 2298 #endif
2250 return result; 2299 return result;
2251 } 2300 }
2252 2301
2253 { MaybeObject* maybe_result = 2302 { MaybeObject* maybe_result =
2254 fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP); 2303 fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP);
2255 if (!maybe_result->ToObject(&result)) return maybe_result; 2304 if (!maybe_result->ToObject(&result)) return maybe_result;
2256 } 2305 }
2257 set(index, result); 2306 set(index, result);
2258 Counters::normalized_maps.Increment(); 2307 COUNTERS->normalized_maps()->Increment();
2259 2308
2260 return result; 2309 return result;
2261 } 2310 }
2262 2311
2263 2312
2264 void NormalizedMapCache::Clear() { 2313 void NormalizedMapCache::Clear() {
2265 int entries = length(); 2314 int entries = length();
2266 for (int i = 0; i != entries; i++) { 2315 for (int i = 0; i != entries; i++) {
2267 set_undefined(i); 2316 set_undefined(i);
2268 } 2317 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 MaybeObject* JSObject::UpdateMapCodeCache(String* name, Code* code) { 2357 MaybeObject* JSObject::UpdateMapCodeCache(String* name, Code* code) {
2309 if (map()->is_shared()) { 2358 if (map()->is_shared()) {
2310 // Fast case maps are never marked as shared. 2359 // Fast case maps are never marked as shared.
2311 ASSERT(!HasFastProperties()); 2360 ASSERT(!HasFastProperties());
2312 // Replace the map with an identical copy that can be safely modified. 2361 // Replace the map with an identical copy that can be safely modified.
2313 Object* obj; 2362 Object* obj;
2314 { MaybeObject* maybe_obj = map()->CopyNormalized(KEEP_INOBJECT_PROPERTIES, 2363 { MaybeObject* maybe_obj = map()->CopyNormalized(KEEP_INOBJECT_PROPERTIES,
2315 UNIQUE_NORMALIZED_MAP); 2364 UNIQUE_NORMALIZED_MAP);
2316 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 2365 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2317 } 2366 }
2318 Counters::normalized_maps.Increment(); 2367 COUNTERS->normalized_maps()->Increment();
2319 2368
2320 set_map(Map::cast(obj)); 2369 set_map(Map::cast(obj));
2321 } 2370 }
2322 return map()->UpdateCodeCache(name, code); 2371 return map()->UpdateCodeCache(name, code);
2323 } 2372 }
2324 2373
2325 2374
2326 MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode, 2375 MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
2327 int expected_additional_properties) { 2376 int expected_additional_properties) {
2328 if (!HasFastProperties()) return this; 2377 if (!HasFastProperties()) return this;
2329 2378
2330 // The global object is always normalized. 2379 // The global object is always normalized.
2331 ASSERT(!IsGlobalObject()); 2380 ASSERT(!IsGlobalObject());
2332
2333 // JSGlobalProxy must never be normalized 2381 // JSGlobalProxy must never be normalized
2334 ASSERT(!IsJSGlobalProxy()); 2382 ASSERT(!IsJSGlobalProxy());
2335 2383
2384 Heap* heap = GetHeap();
2385
2336 // Allocate new content. 2386 // Allocate new content.
2337 int property_count = map()->NumberOfDescribedProperties(); 2387 int property_count = map()->NumberOfDescribedProperties();
2338 if (expected_additional_properties > 0) { 2388 if (expected_additional_properties > 0) {
2339 property_count += expected_additional_properties; 2389 property_count += expected_additional_properties;
2340 } else { 2390 } else {
2341 property_count += 2; // Make space for two more properties. 2391 property_count += 2; // Make space for two more properties.
2342 } 2392 }
2343 Object* obj; 2393 Object* obj;
2344 { MaybeObject* maybe_obj = 2394 { MaybeObject* maybe_obj =
2345 StringDictionary::Allocate(property_count); 2395 StringDictionary::Allocate(property_count);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2394 break; 2444 break;
2395 default: 2445 default:
2396 UNREACHABLE(); 2446 UNREACHABLE();
2397 } 2447 }
2398 } 2448 }
2399 2449
2400 // Copy the next enumeration index from instance descriptor. 2450 // Copy the next enumeration index from instance descriptor.
2401 int index = map()->instance_descriptors()->NextEnumerationIndex(); 2451 int index = map()->instance_descriptors()->NextEnumerationIndex();
2402 dictionary->SetNextEnumerationIndex(index); 2452 dictionary->SetNextEnumerationIndex(index);
2403 2453
2404 { MaybeObject* maybe_obj = Top::context()->global_context()-> 2454 { MaybeObject* maybe_obj = heap->isolate()->context()->global_context()->
2405 normalized_map_cache()->Get(this, mode); 2455 normalized_map_cache()->Get(this, mode);
2406 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 2456 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2407 } 2457 }
2408 Map* new_map = Map::cast(obj); 2458 Map* new_map = Map::cast(obj);
2409 2459
2410 // We have now successfully allocated all the necessary objects. 2460 // We have now successfully allocated all the necessary objects.
2411 // Changes can now be made with the guarantee that all of them take effect. 2461 // Changes can now be made with the guarantee that all of them take effect.
2412 2462
2413 // Resize the object in the heap if necessary. 2463 // Resize the object in the heap if necessary.
2414 int new_instance_size = new_map->instance_size(); 2464 int new_instance_size = new_map->instance_size();
2415 int instance_size_delta = map()->instance_size() - new_instance_size; 2465 int instance_size_delta = map()->instance_size() - new_instance_size;
2416 ASSERT(instance_size_delta >= 0); 2466 ASSERT(instance_size_delta >= 0);
2417 Heap::CreateFillerObjectAt(this->address() + new_instance_size, 2467 heap->CreateFillerObjectAt(this->address() + new_instance_size,
2418 instance_size_delta); 2468 instance_size_delta);
2419 2469
2420 set_map(new_map); 2470 set_map(new_map);
2471 map()->set_instance_descriptors(heap->empty_descriptor_array());
2421 2472
2422 set_properties(dictionary); 2473 set_properties(dictionary);
2423 2474
2424 Counters::props_to_dictionary.Increment(); 2475 heap->isolate()->counters()->props_to_dictionary()->Increment();
2425 2476
2426 #ifdef DEBUG 2477 #ifdef DEBUG
2427 if (FLAG_trace_normalization) { 2478 if (FLAG_trace_normalization) {
2428 PrintF("Object properties have been normalized:\n"); 2479 PrintF("Object properties have been normalized:\n");
2429 Print(); 2480 Print();
2430 } 2481 }
2431 #endif 2482 #endif
2432 return this; 2483 return this;
2433 } 2484 }
2434 2485
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2475 } 2526 }
2476 dictionary = NumberDictionary::cast(result); 2527 dictionary = NumberDictionary::cast(result);
2477 } 2528 }
2478 } 2529 }
2479 // Switch to using the dictionary as the backing storage for 2530 // Switch to using the dictionary as the backing storage for
2480 // elements. Set the new map first to satify the elements type 2531 // elements. Set the new map first to satify the elements type
2481 // assert in set_elements(). 2532 // assert in set_elements().
2482 set_map(new_map); 2533 set_map(new_map);
2483 set_elements(dictionary); 2534 set_elements(dictionary);
2484 2535
2485 Counters::elements_to_dictionary.Increment(); 2536 new_map->GetHeap()->isolate()->counters()->elements_to_dictionary()->
2537 Increment();
2486 2538
2487 #ifdef DEBUG 2539 #ifdef DEBUG
2488 if (FLAG_trace_normalization) { 2540 if (FLAG_trace_normalization) {
2489 PrintF("Object elements have been normalized:\n"); 2541 PrintF("Object elements have been normalized:\n");
2490 Print(); 2542 Print();
2491 } 2543 }
2492 #endif 2544 #endif
2493 2545
2494 return this; 2546 return this;
2495 } 2547 }
2496 2548
2497 2549
2498 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, 2550 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name,
2499 DeleteMode mode) { 2551 DeleteMode mode) {
2500 // Check local property, ignore interceptor. 2552 // Check local property, ignore interceptor.
2553 Heap* heap = GetHeap();
2501 LookupResult result; 2554 LookupResult result;
2502 LocalLookupRealNamedProperty(name, &result); 2555 LocalLookupRealNamedProperty(name, &result);
2503 if (!result.IsProperty()) return Heap::true_value(); 2556 if (!result.IsProperty()) return heap->true_value();
2504 2557
2505 // Normalize object if needed. 2558 // Normalize object if needed.
2506 Object* obj; 2559 Object* obj;
2507 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 2560 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2508 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 2561 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2509 } 2562 }
2510 2563
2511 return DeleteNormalizedProperty(name, mode); 2564 return DeleteNormalizedProperty(name, mode);
2512 } 2565 }
2513 2566
2514 2567
2515 MaybeObject* JSObject::DeletePropertyWithInterceptor(String* name) { 2568 MaybeObject* JSObject::DeletePropertyWithInterceptor(String* name) {
2516 HandleScope scope; 2569 Isolate* isolate = GetIsolate();
2570 HandleScope scope(isolate);
2517 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); 2571 Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
2518 Handle<String> name_handle(name); 2572 Handle<String> name_handle(name);
2519 Handle<JSObject> this_handle(this); 2573 Handle<JSObject> this_handle(this);
2520 if (!interceptor->deleter()->IsUndefined()) { 2574 if (!interceptor->deleter()->IsUndefined()) {
2521 v8::NamedPropertyDeleter deleter = 2575 v8::NamedPropertyDeleter deleter =
2522 v8::ToCData<v8::NamedPropertyDeleter>(interceptor->deleter()); 2576 v8::ToCData<v8::NamedPropertyDeleter>(interceptor->deleter());
2523 LOG(ApiNamedPropertyAccess("interceptor-named-delete", *this_handle, name)); 2577 LOG(isolate,
2524 CustomArguments args(interceptor->data(), this, this); 2578 ApiNamedPropertyAccess("interceptor-named-delete", *this_handle, name));
2579 CustomArguments args(isolate, interceptor->data(), this, this);
2525 v8::AccessorInfo info(args.end()); 2580 v8::AccessorInfo info(args.end());
2526 v8::Handle<v8::Boolean> result; 2581 v8::Handle<v8::Boolean> result;
2527 { 2582 {
2528 // Leaving JavaScript. 2583 // Leaving JavaScript.
2529 VMState state(EXTERNAL); 2584 VMState state(isolate, EXTERNAL);
2530 result = deleter(v8::Utils::ToLocal(name_handle), info); 2585 result = deleter(v8::Utils::ToLocal(name_handle), info);
2531 } 2586 }
2532 RETURN_IF_SCHEDULED_EXCEPTION(); 2587 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
2533 if (!result.IsEmpty()) { 2588 if (!result.IsEmpty()) {
2534 ASSERT(result->IsBoolean()); 2589 ASSERT(result->IsBoolean());
2535 return *v8::Utils::OpenHandle(*result); 2590 return *v8::Utils::OpenHandle(*result);
2536 } 2591 }
2537 } 2592 }
2538 MaybeObject* raw_result = 2593 MaybeObject* raw_result =
2539 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION); 2594 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION);
2540 RETURN_IF_SCHEDULED_EXCEPTION(); 2595 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
2541 return raw_result; 2596 return raw_result;
2542 } 2597 }
2543 2598
2544 2599
2545 MaybeObject* JSObject::DeleteElementPostInterceptor(uint32_t index, 2600 MaybeObject* JSObject::DeleteElementPostInterceptor(uint32_t index,
2546 DeleteMode mode) { 2601 DeleteMode mode) {
2602 Heap* heap = GetHeap();
2547 ASSERT(!HasExternalArrayElements()); 2603 ASSERT(!HasExternalArrayElements());
2548 switch (GetElementsKind()) { 2604 switch (GetElementsKind()) {
2549 case FAST_ELEMENTS: { 2605 case FAST_ELEMENTS: {
2550 Object* obj; 2606 Object* obj;
2551 { MaybeObject* maybe_obj = EnsureWritableFastElements(); 2607 { MaybeObject* maybe_obj = EnsureWritableFastElements();
2552 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 2608 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2553 } 2609 }
2554 uint32_t length = IsJSArray() ? 2610 uint32_t length = IsJSArray() ?
2555 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : 2611 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) :
2556 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 2612 static_cast<uint32_t>(FixedArray::cast(elements())->length());
2557 if (index < length) { 2613 if (index < length) {
2558 FixedArray::cast(elements())->set_the_hole(index); 2614 FixedArray::cast(elements())->set_the_hole(index);
2559 } 2615 }
2560 break; 2616 break;
2561 } 2617 }
2562 case DICTIONARY_ELEMENTS: { 2618 case DICTIONARY_ELEMENTS: {
2563 NumberDictionary* dictionary = element_dictionary(); 2619 NumberDictionary* dictionary = element_dictionary();
2564 int entry = dictionary->FindEntry(index); 2620 int entry = dictionary->FindEntry(index);
2565 if (entry != NumberDictionary::kNotFound) { 2621 if (entry != NumberDictionary::kNotFound) {
2566 return dictionary->DeleteProperty(entry, mode); 2622 return dictionary->DeleteProperty(entry, mode);
2567 } 2623 }
2568 break; 2624 break;
2569 } 2625 }
2570 default: 2626 default:
2571 UNREACHABLE(); 2627 UNREACHABLE();
2572 break; 2628 break;
2573 } 2629 }
2574 return Heap::true_value(); 2630 return heap->true_value();
2575 } 2631 }
2576 2632
2577 2633
2578 MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) { 2634 MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) {
2635 Isolate* isolate = GetIsolate();
2636 Heap* heap = isolate->heap();
2579 // Make sure that the top context does not change when doing 2637 // Make sure that the top context does not change when doing
2580 // callbacks or interceptor calls. 2638 // callbacks or interceptor calls.
2581 AssertNoContextChange ncc; 2639 AssertNoContextChange ncc;
2582 HandleScope scope; 2640 HandleScope scope(isolate);
2583 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); 2641 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
2584 if (interceptor->deleter()->IsUndefined()) return Heap::false_value(); 2642 if (interceptor->deleter()->IsUndefined()) return heap->false_value();
2585 v8::IndexedPropertyDeleter deleter = 2643 v8::IndexedPropertyDeleter deleter =
2586 v8::ToCData<v8::IndexedPropertyDeleter>(interceptor->deleter()); 2644 v8::ToCData<v8::IndexedPropertyDeleter>(interceptor->deleter());
2587 Handle<JSObject> this_handle(this); 2645 Handle<JSObject> this_handle(this);
2588 LOG(ApiIndexedPropertyAccess("interceptor-indexed-delete", this, index)); 2646 LOG(isolate,
2589 CustomArguments args(interceptor->data(), this, this); 2647 ApiIndexedPropertyAccess("interceptor-indexed-delete", this, index));
2648 CustomArguments args(isolate, interceptor->data(), this, this);
2590 v8::AccessorInfo info(args.end()); 2649 v8::AccessorInfo info(args.end());
2591 v8::Handle<v8::Boolean> result; 2650 v8::Handle<v8::Boolean> result;
2592 { 2651 {
2593 // Leaving JavaScript. 2652 // Leaving JavaScript.
2594 VMState state(EXTERNAL); 2653 VMState state(isolate, EXTERNAL);
2595 result = deleter(index, info); 2654 result = deleter(index, info);
2596 } 2655 }
2597 RETURN_IF_SCHEDULED_EXCEPTION(); 2656 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
2598 if (!result.IsEmpty()) { 2657 if (!result.IsEmpty()) {
2599 ASSERT(result->IsBoolean()); 2658 ASSERT(result->IsBoolean());
2600 return *v8::Utils::OpenHandle(*result); 2659 return *v8::Utils::OpenHandle(*result);
2601 } 2660 }
2602 MaybeObject* raw_result = 2661 MaybeObject* raw_result =
2603 this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION); 2662 this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION);
2604 RETURN_IF_SCHEDULED_EXCEPTION(); 2663 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
2605 return raw_result; 2664 return raw_result;
2606 } 2665 }
2607 2666
2608 2667
2609 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { 2668 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
2669 Isolate* isolate = GetIsolate();
2610 // Check access rights if needed. 2670 // Check access rights if needed.
2611 if (IsAccessCheckNeeded() && 2671 if (IsAccessCheckNeeded() &&
2612 !Top::MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { 2672 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) {
2613 Top::ReportFailedAccessCheck(this, v8::ACCESS_DELETE); 2673 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE);
2614 return Heap::false_value(); 2674 return isolate->heap()->false_value();
2615 } 2675 }
2616 2676
2617 if (IsJSGlobalProxy()) { 2677 if (IsJSGlobalProxy()) {
2618 Object* proto = GetPrototype(); 2678 Object* proto = GetPrototype();
2619 if (proto->IsNull()) return Heap::false_value(); 2679 if (proto->IsNull()) return isolate->heap()->false_value();
2620 ASSERT(proto->IsJSGlobalObject()); 2680 ASSERT(proto->IsJSGlobalObject());
2621 return JSGlobalObject::cast(proto)->DeleteElement(index, mode); 2681 return JSGlobalObject::cast(proto)->DeleteElement(index, mode);
2622 } 2682 }
2623 2683
2624 if (HasIndexedInterceptor()) { 2684 if (HasIndexedInterceptor()) {
2625 // Skip interceptor if forcing deletion. 2685 // Skip interceptor if forcing deletion.
2626 if (mode == FORCE_DELETION) { 2686 if (mode == FORCE_DELETION) {
2627 return DeleteElementPostInterceptor(index, mode); 2687 return DeleteElementPostInterceptor(index, mode);
2628 } 2688 }
2629 return DeleteElementWithInterceptor(index); 2689 return DeleteElementWithInterceptor(index);
(...skipping 22 matching lines...) Expand all
2652 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 2712 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
2653 case EXTERNAL_FLOAT_ELEMENTS: 2713 case EXTERNAL_FLOAT_ELEMENTS:
2654 // Pixel and external array elements cannot be deleted. Just 2714 // Pixel and external array elements cannot be deleted. Just
2655 // silently ignore here. 2715 // silently ignore here.
2656 break; 2716 break;
2657 case DICTIONARY_ELEMENTS: { 2717 case DICTIONARY_ELEMENTS: {
2658 NumberDictionary* dictionary = element_dictionary(); 2718 NumberDictionary* dictionary = element_dictionary();
2659 int entry = dictionary->FindEntry(index); 2719 int entry = dictionary->FindEntry(index);
2660 if (entry != NumberDictionary::kNotFound) { 2720 if (entry != NumberDictionary::kNotFound) {
2661 Object* result = dictionary->DeleteProperty(entry, mode); 2721 Object* result = dictionary->DeleteProperty(entry, mode);
2662 if (mode == STRICT_DELETION && result == Heap::false_value()) { 2722 if (mode == STRICT_DELETION && result ==
2723 isolate->heap()->false_value()) {
2663 // In strict mode, deleting a non-configurable property throws 2724 // In strict mode, deleting a non-configurable property throws
2664 // exception. dictionary->DeleteProperty will return false_value() 2725 // exception. dictionary->DeleteProperty will return false_value()
2665 // if a non-configurable property is being deleted. 2726 // if a non-configurable property is being deleted.
2666 HandleScope scope; 2727 HandleScope scope;
2667 Handle<Object> i = Factory::NewNumberFromUint(index); 2728 Handle<Object> i = isolate->factory()->NewNumberFromUint(index);
2668 Handle<Object> args[2] = { i, Handle<Object>(this) }; 2729 Handle<Object> args[2] = { i, Handle<Object>(this) };
2669 return Top::Throw(*Factory::NewTypeError("strict_delete_property", 2730 return isolate->Throw(*isolate->factory()->NewTypeError(
2670 HandleVector(args, 2))); 2731 "strict_delete_property", HandleVector(args, 2)));
2671 } 2732 }
2672 } 2733 }
2673 break; 2734 break;
2674 } 2735 }
2675 default: 2736 default:
2676 UNREACHABLE(); 2737 UNREACHABLE();
2677 break; 2738 break;
2678 } 2739 }
2679 return Heap::true_value(); 2740 return isolate->heap()->true_value();
2680 } 2741 }
2681 2742
2682 2743
2683 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) { 2744 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) {
2745 Isolate* isolate = GetIsolate();
2684 // ECMA-262, 3rd, 8.6.2.5 2746 // ECMA-262, 3rd, 8.6.2.5
2685 ASSERT(name->IsString()); 2747 ASSERT(name->IsString());
2686 2748
2687 // Check access rights if needed. 2749 // Check access rights if needed.
2688 if (IsAccessCheckNeeded() && 2750 if (IsAccessCheckNeeded() &&
2689 !Top::MayNamedAccess(this, name, v8::ACCESS_DELETE)) { 2751 !isolate->MayNamedAccess(this, name, v8::ACCESS_DELETE)) {
2690 Top::ReportFailedAccessCheck(this, v8::ACCESS_DELETE); 2752 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE);
2691 return Heap::false_value(); 2753 return isolate->heap()->false_value();
2692 } 2754 }
2693 2755
2694 if (IsJSGlobalProxy()) { 2756 if (IsJSGlobalProxy()) {
2695 Object* proto = GetPrototype(); 2757 Object* proto = GetPrototype();
2696 if (proto->IsNull()) return Heap::false_value(); 2758 if (proto->IsNull()) return isolate->heap()->false_value();
2697 ASSERT(proto->IsJSGlobalObject()); 2759 ASSERT(proto->IsJSGlobalObject());
2698 return JSGlobalObject::cast(proto)->DeleteProperty(name, mode); 2760 return JSGlobalObject::cast(proto)->DeleteProperty(name, mode);
2699 } 2761 }
2700 2762
2701 uint32_t index = 0; 2763 uint32_t index = 0;
2702 if (name->AsArrayIndex(&index)) { 2764 if (name->AsArrayIndex(&index)) {
2703 return DeleteElement(index, mode); 2765 return DeleteElement(index, mode);
2704 } else { 2766 } else {
2705 LookupResult result; 2767 LookupResult result;
2706 LocalLookup(name, &result); 2768 LocalLookup(name, &result);
2707 if (!result.IsProperty()) return Heap::true_value(); 2769 if (!result.IsProperty()) return isolate->heap()->true_value();
2708 // Ignore attributes if forcing a deletion. 2770 // Ignore attributes if forcing a deletion.
2709 if (result.IsDontDelete() && mode != FORCE_DELETION) { 2771 if (result.IsDontDelete() && mode != FORCE_DELETION) {
2710 if (mode == STRICT_DELETION) { 2772 if (mode == STRICT_DELETION) {
2711 // Deleting a non-configurable property in strict mode. 2773 // Deleting a non-configurable property in strict mode.
2712 HandleScope scope; 2774 HandleScope scope(isolate);
2713 Handle<Object> args[2] = { Handle<Object>(name), Handle<Object>(this) }; 2775 Handle<Object> args[2] = { Handle<Object>(name), Handle<Object>(this) };
2714 return Top::Throw(*Factory::NewTypeError("strict_delete_property", 2776 return isolate->Throw(*isolate->factory()->NewTypeError(
2715 HandleVector(args, 2))); 2777 "strict_delete_property", HandleVector(args, 2)));
2716 } 2778 }
2717 return Heap::false_value(); 2779 return isolate->heap()->false_value();
2718 } 2780 }
2719 // Check for interceptor. 2781 // Check for interceptor.
2720 if (result.type() == INTERCEPTOR) { 2782 if (result.type() == INTERCEPTOR) {
2721 // Skip interceptor if forcing a deletion. 2783 // Skip interceptor if forcing a deletion.
2722 if (mode == FORCE_DELETION) { 2784 if (mode == FORCE_DELETION) {
2723 return DeletePropertyPostInterceptor(name, mode); 2785 return DeletePropertyPostInterceptor(name, mode);
2724 } 2786 }
2725 return DeletePropertyWithInterceptor(name); 2787 return DeletePropertyWithInterceptor(name);
2726 } 2788 }
2727 // Normalize object if needed. 2789 // Normalize object if needed.
2728 Object* obj; 2790 Object* obj;
2729 { MaybeObject* maybe_obj = 2791 { MaybeObject* maybe_obj =
2730 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 2792 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2731 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 2793 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2732 } 2794 }
2733 // Make sure the properties are normalized before removing the entry. 2795 // Make sure the properties are normalized before removing the entry.
2734 return DeleteNormalizedProperty(name, mode); 2796 return DeleteNormalizedProperty(name, mode);
2735 } 2797 }
2736 } 2798 }
2737 2799
2738 2800
2739 // Check whether this object references another object. 2801 // Check whether this object references another object.
2740 bool JSObject::ReferencesObject(Object* obj) { 2802 bool JSObject::ReferencesObject(Object* obj) {
2803 Heap* heap = GetHeap();
2741 AssertNoAllocation no_alloc; 2804 AssertNoAllocation no_alloc;
2742 2805
2743 // Is the object the constructor for this object? 2806 // Is the object the constructor for this object?
2744 if (map()->constructor() == obj) { 2807 if (map()->constructor() == obj) {
2745 return true; 2808 return true;
2746 } 2809 }
2747 2810
2748 // Is the object the prototype for this object? 2811 // Is the object the prototype for this object?
2749 if (map()->prototype() == obj) { 2812 if (map()->prototype() == obj) {
2750 return true; 2813 return true;
2751 } 2814 }
2752 2815
2753 // Check if the object is among the named properties. 2816 // Check if the object is among the named properties.
2754 Object* key = SlowReverseLookup(obj); 2817 Object* key = SlowReverseLookup(obj);
2755 if (key != Heap::undefined_value()) { 2818 if (!key->IsUndefined()) {
2756 return true; 2819 return true;
2757 } 2820 }
2758 2821
2759 // Check if the object is among the indexed properties. 2822 // Check if the object is among the indexed properties.
2760 switch (GetElementsKind()) { 2823 switch (GetElementsKind()) {
2761 case EXTERNAL_PIXEL_ELEMENTS: 2824 case EXTERNAL_PIXEL_ELEMENTS:
2762 case EXTERNAL_BYTE_ELEMENTS: 2825 case EXTERNAL_BYTE_ELEMENTS:
2763 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 2826 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
2764 case EXTERNAL_SHORT_ELEMENTS: 2827 case EXTERNAL_SHORT_ELEMENTS:
2765 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 2828 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
(...skipping 10 matching lines...) Expand all
2776 for (int i = 0; i < length; i++) { 2839 for (int i = 0; i < length; i++) {
2777 Object* element = FixedArray::cast(elements())->get(i); 2840 Object* element = FixedArray::cast(elements())->get(i);
2778 if (!element->IsTheHole() && element == obj) { 2841 if (!element->IsTheHole() && element == obj) {
2779 return true; 2842 return true;
2780 } 2843 }
2781 } 2844 }
2782 break; 2845 break;
2783 } 2846 }
2784 case DICTIONARY_ELEMENTS: { 2847 case DICTIONARY_ELEMENTS: {
2785 key = element_dictionary()->SlowReverseLookup(obj); 2848 key = element_dictionary()->SlowReverseLookup(obj);
2786 if (key != Heap::undefined_value()) { 2849 if (!key->IsUndefined()) {
2787 return true; 2850 return true;
2788 } 2851 }
2789 break; 2852 break;
2790 } 2853 }
2791 default: 2854 default:
2792 UNREACHABLE(); 2855 UNREACHABLE();
2793 break; 2856 break;
2794 } 2857 }
2795 2858
2796 // For functions check the context. 2859 // For functions check the context.
2797 if (IsJSFunction()) { 2860 if (IsJSFunction()) {
2798 // Get the constructor function for arguments array. 2861 // Get the constructor function for arguments array.
2799 JSObject* arguments_boilerplate = 2862 JSObject* arguments_boilerplate =
2800 Top::context()->global_context()->arguments_boilerplate(); 2863 heap->isolate()->context()->global_context()->
2864 arguments_boilerplate();
2801 JSFunction* arguments_function = 2865 JSFunction* arguments_function =
2802 JSFunction::cast(arguments_boilerplate->map()->constructor()); 2866 JSFunction::cast(arguments_boilerplate->map()->constructor());
2803 2867
2804 // Get the context and don't check if it is the global context. 2868 // Get the context and don't check if it is the global context.
2805 JSFunction* f = JSFunction::cast(this); 2869 JSFunction* f = JSFunction::cast(this);
2806 Context* context = f->context(); 2870 Context* context = f->context();
2807 if (context->IsGlobalContext()) { 2871 if (context->IsGlobalContext()) {
2808 return false; 2872 return false;
2809 } 2873 }
2810 2874
(...skipping 18 matching lines...) Expand all
2829 return context->extension()->ReferencesObject(obj); 2893 return context->extension()->ReferencesObject(obj);
2830 } 2894 }
2831 } 2895 }
2832 2896
2833 // No references to object. 2897 // No references to object.
2834 return false; 2898 return false;
2835 } 2899 }
2836 2900
2837 2901
2838 MaybeObject* JSObject::PreventExtensions() { 2902 MaybeObject* JSObject::PreventExtensions() {
2903 Isolate* isolate = GetIsolate();
2839 if (IsAccessCheckNeeded() && 2904 if (IsAccessCheckNeeded() &&
2840 !Top::MayNamedAccess(this, Heap::undefined_value(), v8::ACCESS_KEYS)) { 2905 !isolate->MayNamedAccess(this,
2841 Top::ReportFailedAccessCheck(this, v8::ACCESS_KEYS); 2906 isolate->heap()->undefined_value(),
2842 return Heap::false_value(); 2907 v8::ACCESS_KEYS)) {
2908 isolate->ReportFailedAccessCheck(this, v8::ACCESS_KEYS);
2909 return isolate->heap()->false_value();
2843 } 2910 }
2844 2911
2845 if (IsJSGlobalProxy()) { 2912 if (IsJSGlobalProxy()) {
2846 Object* proto = GetPrototype(); 2913 Object* proto = GetPrototype();
2847 if (proto->IsNull()) return this; 2914 if (proto->IsNull()) return this;
2848 ASSERT(proto->IsJSGlobalObject()); 2915 ASSERT(proto->IsJSGlobalObject());
2849 return JSObject::cast(proto)->PreventExtensions(); 2916 return JSObject::cast(proto)->PreventExtensions();
2850 } 2917 }
2851 2918
2852 // If there are fast elements we normalize. 2919 // If there are fast elements we normalize.
(...skipping 18 matching lines...) Expand all
2871 return new_map; 2938 return new_map;
2872 } 2939 }
2873 2940
2874 2941
2875 // Tests for the fast common case for property enumeration: 2942 // Tests for the fast common case for property enumeration:
2876 // - This object and all prototypes has an enum cache (which means that it has 2943 // - This object and all prototypes has an enum cache (which means that it has
2877 // no interceptors and needs no access checks). 2944 // no interceptors and needs no access checks).
2878 // - This object has no elements. 2945 // - This object has no elements.
2879 // - No prototype has enumerable properties/elements. 2946 // - No prototype has enumerable properties/elements.
2880 bool JSObject::IsSimpleEnum() { 2947 bool JSObject::IsSimpleEnum() {
2948 Heap* heap = GetHeap();
2881 for (Object* o = this; 2949 for (Object* o = this;
2882 o != Heap::null_value(); 2950 o != heap->null_value();
2883 o = JSObject::cast(o)->GetPrototype()) { 2951 o = JSObject::cast(o)->GetPrototype()) {
2884 JSObject* curr = JSObject::cast(o); 2952 JSObject* curr = JSObject::cast(o);
2885 if (!curr->map()->instance_descriptors()->HasEnumCache()) return false; 2953 if (!curr->map()->instance_descriptors()->HasEnumCache()) return false;
2886 ASSERT(!curr->HasNamedInterceptor()); 2954 ASSERT(!curr->HasNamedInterceptor());
2887 ASSERT(!curr->HasIndexedInterceptor()); 2955 ASSERT(!curr->HasIndexedInterceptor());
2888 ASSERT(!curr->IsAccessCheckNeeded()); 2956 ASSERT(!curr->IsAccessCheckNeeded());
2889 if (curr->NumberOfEnumElements() > 0) return false; 2957 if (curr->NumberOfEnumElements() > 0) return false;
2890 if (curr != this) { 2958 if (curr != this) {
2891 FixedArray* curr_fixed_array = 2959 FixedArray* curr_fixed_array =
2892 FixedArray::cast(curr->map()->instance_descriptors()->GetEnumCache()); 2960 FixedArray::cast(curr->map()->instance_descriptors()->GetEnumCache());
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2938 return descs->GetCallbacks(i); 3006 return descs->GetCallbacks(i);
2939 } 3007 }
2940 } 3008 }
2941 return NULL; 3009 return NULL;
2942 } 3010 }
2943 3011
2944 3012
2945 void JSObject::LocalLookup(String* name, LookupResult* result) { 3013 void JSObject::LocalLookup(String* name, LookupResult* result) {
2946 ASSERT(name->IsString()); 3014 ASSERT(name->IsString());
2947 3015
3016 Heap* heap = GetHeap();
3017
2948 if (IsJSGlobalProxy()) { 3018 if (IsJSGlobalProxy()) {
2949 Object* proto = GetPrototype(); 3019 Object* proto = GetPrototype();
2950 if (proto->IsNull()) return result->NotFound(); 3020 if (proto->IsNull()) return result->NotFound();
2951 ASSERT(proto->IsJSGlobalObject()); 3021 ASSERT(proto->IsJSGlobalObject());
2952 return JSObject::cast(proto)->LocalLookup(name, result); 3022 return JSObject::cast(proto)->LocalLookup(name, result);
2953 } 3023 }
2954 3024
2955 // Do not use inline caching if the object is a non-global object 3025 // Do not use inline caching if the object is a non-global object
2956 // that requires access checks. 3026 // that requires access checks.
2957 if (!IsJSGlobalProxy() && IsAccessCheckNeeded()) { 3027 if (!IsJSGlobalProxy() && IsAccessCheckNeeded()) {
2958 result->DisallowCaching(); 3028 result->DisallowCaching();
2959 } 3029 }
2960 3030
2961 // Check __proto__ before interceptor. 3031 // Check __proto__ before interceptor.
2962 if (name->Equals(Heap::Proto_symbol()) && !IsJSContextExtensionObject()) { 3032 if (name->Equals(heap->Proto_symbol()) &&
3033 !IsJSContextExtensionObject()) {
2963 result->ConstantResult(this); 3034 result->ConstantResult(this);
2964 return; 3035 return;
2965 } 3036 }
2966 3037
2967 // Check for lookup interceptor except when bootstrapping. 3038 // Check for lookup interceptor except when bootstrapping.
2968 if (HasNamedInterceptor() && !Bootstrapper::IsActive()) { 3039 if (HasNamedInterceptor() && !heap->isolate()->bootstrapper()->IsActive()) {
2969 result->InterceptorResult(this); 3040 result->InterceptorResult(this);
2970 return; 3041 return;
2971 } 3042 }
2972 3043
2973 LocalLookupRealNamedProperty(name, result); 3044 LocalLookupRealNamedProperty(name, result);
2974 } 3045 }
2975 3046
2976 3047
2977 void JSObject::Lookup(String* name, LookupResult* result) { 3048 void JSObject::Lookup(String* name, LookupResult* result) {
2978 // Ecma-262 3rd 8.6.2.4 3049 // Ecma-262 3rd 8.6.2.4
3050 Heap* heap = GetHeap();
2979 for (Object* current = this; 3051 for (Object* current = this;
2980 current != Heap::null_value(); 3052 current != heap->null_value();
2981 current = JSObject::cast(current)->GetPrototype()) { 3053 current = JSObject::cast(current)->GetPrototype()) {
2982 JSObject::cast(current)->LocalLookup(name, result); 3054 JSObject::cast(current)->LocalLookup(name, result);
2983 if (result->IsProperty()) return; 3055 if (result->IsProperty()) return;
2984 } 3056 }
2985 result->NotFound(); 3057 result->NotFound();
2986 } 3058 }
2987 3059
2988 3060
2989 // Search object and it's prototype chain for callback properties. 3061 // Search object and it's prototype chain for callback properties.
2990 void JSObject::LookupCallback(String* name, LookupResult* result) { 3062 void JSObject::LookupCallback(String* name, LookupResult* result) {
3063 Heap* heap = GetHeap();
2991 for (Object* current = this; 3064 for (Object* current = this;
2992 current != Heap::null_value(); 3065 current != heap->null_value();
2993 current = JSObject::cast(current)->GetPrototype()) { 3066 current = JSObject::cast(current)->GetPrototype()) {
2994 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); 3067 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result);
2995 if (result->IsProperty() && result->type() == CALLBACKS) return; 3068 if (result->IsProperty() && result->type() == CALLBACKS) return;
2996 } 3069 }
2997 result->NotFound(); 3070 result->NotFound();
2998 } 3071 }
2999 3072
3000 3073
3001 MaybeObject* JSObject::DefineGetterSetter(String* name, 3074 MaybeObject* JSObject::DefineGetterSetter(String* name,
3002 PropertyAttributes attributes) { 3075 PropertyAttributes attributes) {
3076 Heap* heap = GetHeap();
3003 // Make sure that the top context does not change when doing callbacks or 3077 // Make sure that the top context does not change when doing callbacks or
3004 // interceptor calls. 3078 // interceptor calls.
3005 AssertNoContextChange ncc; 3079 AssertNoContextChange ncc;
3006 3080
3007 // Try to flatten before operating on the string. 3081 // Try to flatten before operating on the string.
3008 name->TryFlatten(); 3082 name->TryFlatten();
3009 3083
3010 if (!CanSetCallback(name)) { 3084 if (!CanSetCallback(name)) {
3011 return Heap::undefined_value(); 3085 return heap->undefined_value();
3012 } 3086 }
3013 3087
3014 uint32_t index = 0; 3088 uint32_t index = 0;
3015 bool is_element = name->AsArrayIndex(&index); 3089 bool is_element = name->AsArrayIndex(&index);
3016 3090
3017 if (is_element) { 3091 if (is_element) {
3018 switch (GetElementsKind()) { 3092 switch (GetElementsKind()) {
3019 case FAST_ELEMENTS: 3093 case FAST_ELEMENTS:
3020 break; 3094 break;
3021 case EXTERNAL_PIXEL_ELEMENTS: 3095 case EXTERNAL_PIXEL_ELEMENTS:
3022 case EXTERNAL_BYTE_ELEMENTS: 3096 case EXTERNAL_BYTE_ELEMENTS:
3023 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3097 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3024 case EXTERNAL_SHORT_ELEMENTS: 3098 case EXTERNAL_SHORT_ELEMENTS:
3025 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3099 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3026 case EXTERNAL_INT_ELEMENTS: 3100 case EXTERNAL_INT_ELEMENTS:
3027 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3101 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3028 case EXTERNAL_FLOAT_ELEMENTS: 3102 case EXTERNAL_FLOAT_ELEMENTS:
3029 // Ignore getters and setters on pixel and external array 3103 // Ignore getters and setters on pixel and external array
3030 // elements. 3104 // elements.
3031 return Heap::undefined_value(); 3105 return heap->undefined_value();
3032 case DICTIONARY_ELEMENTS: { 3106 case DICTIONARY_ELEMENTS: {
3033 // Lookup the index. 3107 // Lookup the index.
3034 NumberDictionary* dictionary = element_dictionary(); 3108 NumberDictionary* dictionary = element_dictionary();
3035 int entry = dictionary->FindEntry(index); 3109 int entry = dictionary->FindEntry(index);
3036 if (entry != NumberDictionary::kNotFound) { 3110 if (entry != NumberDictionary::kNotFound) {
3037 Object* result = dictionary->ValueAt(entry); 3111 Object* result = dictionary->ValueAt(entry);
3038 PropertyDetails details = dictionary->DetailsAt(entry); 3112 PropertyDetails details = dictionary->DetailsAt(entry);
3039 if (details.IsReadOnly()) return Heap::undefined_value(); 3113 if (details.IsReadOnly()) return heap->undefined_value();
3040 if (details.type() == CALLBACKS) { 3114 if (details.type() == CALLBACKS) {
3041 if (result->IsFixedArray()) { 3115 if (result->IsFixedArray()) {
3042 return result; 3116 return result;
3043 } 3117 }
3044 // Otherwise allow to override it. 3118 // Otherwise allow to override it.
3045 } 3119 }
3046 } 3120 }
3047 break; 3121 break;
3048 } 3122 }
3049 default: 3123 default:
3050 UNREACHABLE(); 3124 UNREACHABLE();
3051 break; 3125 break;
3052 } 3126 }
3053 } else { 3127 } else {
3054 // Lookup the name. 3128 // Lookup the name.
3055 LookupResult result; 3129 LookupResult result;
3056 LocalLookup(name, &result); 3130 LocalLookup(name, &result);
3057 if (result.IsProperty()) { 3131 if (result.IsProperty()) {
3058 if (result.IsReadOnly()) return Heap::undefined_value(); 3132 if (result.IsReadOnly()) return heap->undefined_value();
3059 if (result.type() == CALLBACKS) { 3133 if (result.type() == CALLBACKS) {
3060 Object* obj = result.GetCallbackObject(); 3134 Object* obj = result.GetCallbackObject();
3061 // Need to preserve old getters/setters. 3135 // Need to preserve old getters/setters.
3062 if (obj->IsFixedArray()) { 3136 if (obj->IsFixedArray()) {
3063 // Use set to update attributes. 3137 // Use set to update attributes.
3064 return SetPropertyCallback(name, obj, attributes); 3138 return SetPropertyCallback(name, obj, attributes);
3065 } 3139 }
3066 } 3140 }
3067 } 3141 }
3068 } 3142 }
3069 3143
3070 // Allocate the fixed array to hold getter and setter. 3144 // Allocate the fixed array to hold getter and setter.
3071 Object* structure; 3145 Object* structure;
3072 { MaybeObject* maybe_structure = Heap::AllocateFixedArray(2, TENURED); 3146 { MaybeObject* maybe_structure = heap->AllocateFixedArray(2, TENURED);
3073 if (!maybe_structure->ToObject(&structure)) return maybe_structure; 3147 if (!maybe_structure->ToObject(&structure)) return maybe_structure;
3074 } 3148 }
3075 3149
3076 if (is_element) { 3150 if (is_element) {
3077 return SetElementCallback(index, structure, attributes); 3151 return SetElementCallback(index, structure, attributes);
3078 } else { 3152 } else {
3079 return SetPropertyCallback(name, structure, attributes); 3153 return SetPropertyCallback(name, structure, attributes);
3080 } 3154 }
3081 } 3155 }
3082 3156
3083 3157
3084 bool JSObject::CanSetCallback(String* name) { 3158 bool JSObject::CanSetCallback(String* name) {
3085 ASSERT(!IsAccessCheckNeeded() 3159 ASSERT(!IsAccessCheckNeeded()
3086 || Top::MayNamedAccess(this, name, v8::ACCESS_SET)); 3160 || Isolate::Current()->MayNamedAccess(this, name, v8::ACCESS_SET));
3087 3161
3088 // Check if there is an API defined callback object which prohibits 3162 // Check if there is an API defined callback object which prohibits
3089 // callback overwriting in this object or it's prototype chain. 3163 // callback overwriting in this object or it's prototype chain.
3090 // This mechanism is needed for instance in a browser setting, where 3164 // This mechanism is needed for instance in a browser setting, where
3091 // certain accessors such as window.location should not be allowed 3165 // certain accessors such as window.location should not be allowed
3092 // to be overwritten because allowing overwriting could potentially 3166 // to be overwritten because allowing overwriting could potentially
3093 // cause security problems. 3167 // cause security problems.
3094 LookupResult callback_result; 3168 LookupResult callback_result;
3095 LookupCallback(name, &callback_result); 3169 LookupCallback(name, &callback_result);
3096 if (callback_result.IsProperty()) { 3170 if (callback_result.IsProperty()) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
3173 } 3247 }
3174 } 3248 }
3175 return result; 3249 return result;
3176 } 3250 }
3177 3251
3178 MaybeObject* JSObject::DefineAccessor(String* name, 3252 MaybeObject* JSObject::DefineAccessor(String* name,
3179 bool is_getter, 3253 bool is_getter,
3180 Object* fun, 3254 Object* fun,
3181 PropertyAttributes attributes) { 3255 PropertyAttributes attributes) {
3182 ASSERT(fun->IsJSFunction() || fun->IsUndefined()); 3256 ASSERT(fun->IsJSFunction() || fun->IsUndefined());
3257 Isolate* isolate = GetIsolate();
3183 // Check access rights if needed. 3258 // Check access rights if needed.
3184 if (IsAccessCheckNeeded() && 3259 if (IsAccessCheckNeeded() &&
3185 !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { 3260 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) {
3186 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); 3261 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET);
3187 return Heap::undefined_value(); 3262 return isolate->heap()->undefined_value();
3188 } 3263 }
3189 3264
3190 if (IsJSGlobalProxy()) { 3265 if (IsJSGlobalProxy()) {
3191 Object* proto = GetPrototype(); 3266 Object* proto = GetPrototype();
3192 if (proto->IsNull()) return this; 3267 if (proto->IsNull()) return this;
3193 ASSERT(proto->IsJSGlobalObject()); 3268 ASSERT(proto->IsJSGlobalObject());
3194 return JSObject::cast(proto)->DefineAccessor(name, is_getter, 3269 return JSObject::cast(proto)->DefineAccessor(name, is_getter,
3195 fun, attributes); 3270 fun, attributes);
3196 } 3271 }
3197 3272
3198 Object* array; 3273 Object* array;
3199 { MaybeObject* maybe_array = DefineGetterSetter(name, attributes); 3274 { MaybeObject* maybe_array = DefineGetterSetter(name, attributes);
3200 if (!maybe_array->ToObject(&array)) return maybe_array; 3275 if (!maybe_array->ToObject(&array)) return maybe_array;
3201 } 3276 }
3202 if (array->IsUndefined()) return array; 3277 if (array->IsUndefined()) return array;
3203 FixedArray::cast(array)->set(is_getter ? 0 : 1, fun); 3278 FixedArray::cast(array)->set(is_getter ? 0 : 1, fun);
3204 return this; 3279 return this;
3205 } 3280 }
3206 3281
3207 3282
3208 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) { 3283 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) {
3284 Isolate* isolate = GetIsolate();
3209 String* name = String::cast(info->name()); 3285 String* name = String::cast(info->name());
3210 // Check access rights if needed. 3286 // Check access rights if needed.
3211 if (IsAccessCheckNeeded() && 3287 if (IsAccessCheckNeeded() &&
3212 !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { 3288 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) {
3213 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); 3289 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET);
3214 return Heap::undefined_value(); 3290 return isolate->heap()->undefined_value();
3215 } 3291 }
3216 3292
3217 if (IsJSGlobalProxy()) { 3293 if (IsJSGlobalProxy()) {
3218 Object* proto = GetPrototype(); 3294 Object* proto = GetPrototype();
3219 if (proto->IsNull()) return this; 3295 if (proto->IsNull()) return this;
3220 ASSERT(proto->IsJSGlobalObject()); 3296 ASSERT(proto->IsJSGlobalObject());
3221 return JSObject::cast(proto)->DefineAccessor(info); 3297 return JSObject::cast(proto)->DefineAccessor(info);
3222 } 3298 }
3223 3299
3224 // Make sure that the top context does not change when doing callbacks or 3300 // Make sure that the top context does not change when doing callbacks or
3225 // interceptor calls. 3301 // interceptor calls.
3226 AssertNoContextChange ncc; 3302 AssertNoContextChange ncc;
3227 3303
3228 // Try to flatten before operating on the string. 3304 // Try to flatten before operating on the string.
3229 name->TryFlatten(); 3305 name->TryFlatten();
3230 3306
3231 if (!CanSetCallback(name)) { 3307 if (!CanSetCallback(name)) {
3232 return Heap::undefined_value(); 3308 return isolate->heap()->undefined_value();
3233 } 3309 }
3234 3310
3235 uint32_t index = 0; 3311 uint32_t index = 0;
3236 bool is_element = name->AsArrayIndex(&index); 3312 bool is_element = name->AsArrayIndex(&index);
3237 3313
3238 if (is_element) { 3314 if (is_element) {
3239 if (IsJSArray()) return Heap::undefined_value(); 3315 if (IsJSArray()) return isolate->heap()->undefined_value();
3240 3316
3241 // Accessors overwrite previous callbacks (cf. with getters/setters). 3317 // Accessors overwrite previous callbacks (cf. with getters/setters).
3242 switch (GetElementsKind()) { 3318 switch (GetElementsKind()) {
3243 case FAST_ELEMENTS: 3319 case FAST_ELEMENTS:
3244 break; 3320 break;
3245 case EXTERNAL_PIXEL_ELEMENTS: 3321 case EXTERNAL_PIXEL_ELEMENTS:
3246 case EXTERNAL_BYTE_ELEMENTS: 3322 case EXTERNAL_BYTE_ELEMENTS:
3247 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3323 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3248 case EXTERNAL_SHORT_ELEMENTS: 3324 case EXTERNAL_SHORT_ELEMENTS:
3249 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3325 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3250 case EXTERNAL_INT_ELEMENTS: 3326 case EXTERNAL_INT_ELEMENTS:
3251 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3327 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3252 case EXTERNAL_FLOAT_ELEMENTS: 3328 case EXTERNAL_FLOAT_ELEMENTS:
3253 // Ignore getters and setters on pixel and external array 3329 // Ignore getters and setters on pixel and external array
3254 // elements. 3330 // elements.
3255 return Heap::undefined_value(); 3331 return isolate->heap()->undefined_value();
3256 case DICTIONARY_ELEMENTS: 3332 case DICTIONARY_ELEMENTS:
3257 break; 3333 break;
3258 default: 3334 default:
3259 UNREACHABLE(); 3335 UNREACHABLE();
3260 break; 3336 break;
3261 } 3337 }
3262 3338
3263 Object* ok; 3339 Object* ok;
3264 { MaybeObject* maybe_ok = 3340 { MaybeObject* maybe_ok =
3265 SetElementCallback(index, info, info->property_attributes()); 3341 SetElementCallback(index, info, info->property_attributes());
3266 if (!maybe_ok->ToObject(&ok)) return maybe_ok; 3342 if (!maybe_ok->ToObject(&ok)) return maybe_ok;
3267 } 3343 }
3268 } else { 3344 } else {
3269 // Lookup the name. 3345 // Lookup the name.
3270 LookupResult result; 3346 LookupResult result;
3271 LocalLookup(name, &result); 3347 LocalLookup(name, &result);
3272 // ES5 forbids turning a property into an accessor if it's not 3348 // ES5 forbids turning a property into an accessor if it's not
3273 // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5). 3349 // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5).
3274 if (result.IsProperty() && (result.IsReadOnly() || result.IsDontDelete())) { 3350 if (result.IsProperty() && (result.IsReadOnly() || result.IsDontDelete())) {
3275 return Heap::undefined_value(); 3351 return isolate->heap()->undefined_value();
3276 } 3352 }
3277 Object* ok; 3353 Object* ok;
3278 { MaybeObject* maybe_ok = 3354 { MaybeObject* maybe_ok =
3279 SetPropertyCallback(name, info, info->property_attributes()); 3355 SetPropertyCallback(name, info, info->property_attributes());
3280 if (!maybe_ok->ToObject(&ok)) return maybe_ok; 3356 if (!maybe_ok->ToObject(&ok)) return maybe_ok;
3281 } 3357 }
3282 } 3358 }
3283 3359
3284 return this; 3360 return this;
3285 } 3361 }
3286 3362
3287 3363
3288 Object* JSObject::LookupAccessor(String* name, bool is_getter) { 3364 Object* JSObject::LookupAccessor(String* name, bool is_getter) {
3365 Heap* heap = GetHeap();
3366
3289 // Make sure that the top context does not change when doing callbacks or 3367 // Make sure that the top context does not change when doing callbacks or
3290 // interceptor calls. 3368 // interceptor calls.
3291 AssertNoContextChange ncc; 3369 AssertNoContextChange ncc;
3292 3370
3293 // Check access rights if needed. 3371 // Check access rights if needed.
3294 if (IsAccessCheckNeeded() && 3372 if (IsAccessCheckNeeded() &&
3295 !Top::MayNamedAccess(this, name, v8::ACCESS_HAS)) { 3373 !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) {
3296 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); 3374 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
3297 return Heap::undefined_value(); 3375 return heap->undefined_value();
3298 } 3376 }
3299 3377
3300 // Make the lookup and include prototypes. 3378 // Make the lookup and include prototypes.
3301 int accessor_index = is_getter ? kGetterIndex : kSetterIndex; 3379 int accessor_index = is_getter ? kGetterIndex : kSetterIndex;
3302 uint32_t index = 0; 3380 uint32_t index = 0;
3303 if (name->AsArrayIndex(&index)) { 3381 if (name->AsArrayIndex(&index)) {
3304 for (Object* obj = this; 3382 for (Object* obj = this;
3305 obj != Heap::null_value(); 3383 obj != heap->null_value();
3306 obj = JSObject::cast(obj)->GetPrototype()) { 3384 obj = JSObject::cast(obj)->GetPrototype()) {
3307 JSObject* js_object = JSObject::cast(obj); 3385 JSObject* js_object = JSObject::cast(obj);
3308 if (js_object->HasDictionaryElements()) { 3386 if (js_object->HasDictionaryElements()) {
3309 NumberDictionary* dictionary = js_object->element_dictionary(); 3387 NumberDictionary* dictionary = js_object->element_dictionary();
3310 int entry = dictionary->FindEntry(index); 3388 int entry = dictionary->FindEntry(index);
3311 if (entry != NumberDictionary::kNotFound) { 3389 if (entry != NumberDictionary::kNotFound) {
3312 Object* element = dictionary->ValueAt(entry); 3390 Object* element = dictionary->ValueAt(entry);
3313 PropertyDetails details = dictionary->DetailsAt(entry); 3391 PropertyDetails details = dictionary->DetailsAt(entry);
3314 if (details.type() == CALLBACKS) { 3392 if (details.type() == CALLBACKS) {
3315 if (element->IsFixedArray()) { 3393 if (element->IsFixedArray()) {
3316 return FixedArray::cast(element)->get(accessor_index); 3394 return FixedArray::cast(element)->get(accessor_index);
3317 } 3395 }
3318 } 3396 }
3319 } 3397 }
3320 } 3398 }
3321 } 3399 }
3322 } else { 3400 } else {
3323 for (Object* obj = this; 3401 for (Object* obj = this;
3324 obj != Heap::null_value(); 3402 obj != heap->null_value();
3325 obj = JSObject::cast(obj)->GetPrototype()) { 3403 obj = JSObject::cast(obj)->GetPrototype()) {
3326 LookupResult result; 3404 LookupResult result;
3327 JSObject::cast(obj)->LocalLookup(name, &result); 3405 JSObject::cast(obj)->LocalLookup(name, &result);
3328 if (result.IsProperty()) { 3406 if (result.IsProperty()) {
3329 if (result.IsReadOnly()) return Heap::undefined_value(); 3407 if (result.IsReadOnly()) return heap->undefined_value();
3330 if (result.type() == CALLBACKS) { 3408 if (result.type() == CALLBACKS) {
3331 Object* obj = result.GetCallbackObject(); 3409 Object* obj = result.GetCallbackObject();
3332 if (obj->IsFixedArray()) { 3410 if (obj->IsFixedArray()) {
3333 return FixedArray::cast(obj)->get(accessor_index); 3411 return FixedArray::cast(obj)->get(accessor_index);
3334 } 3412 }
3335 } 3413 }
3336 } 3414 }
3337 } 3415 }
3338 } 3416 }
3339 return Heap::undefined_value(); 3417 return heap->undefined_value();
3340 } 3418 }
3341 3419
3342 3420
3343 Object* JSObject::SlowReverseLookup(Object* value) { 3421 Object* JSObject::SlowReverseLookup(Object* value) {
3422 Heap* heap = GetHeap();
3344 if (HasFastProperties()) { 3423 if (HasFastProperties()) {
3345 DescriptorArray* descs = map()->instance_descriptors(); 3424 DescriptorArray* descs = map()->instance_descriptors();
3346 for (int i = 0; i < descs->number_of_descriptors(); i++) { 3425 for (int i = 0; i < descs->number_of_descriptors(); i++) {
3347 if (descs->GetType(i) == FIELD) { 3426 if (descs->GetType(i) == FIELD) {
3348 if (FastPropertyAt(descs->GetFieldIndex(i)) == value) { 3427 if (FastPropertyAt(descs->GetFieldIndex(i)) == value) {
3349 return descs->GetKey(i); 3428 return descs->GetKey(i);
3350 } 3429 }
3351 } else if (descs->GetType(i) == CONSTANT_FUNCTION) { 3430 } else if (descs->GetType(i) == CONSTANT_FUNCTION) {
3352 if (descs->GetConstantFunction(i) == value) { 3431 if (descs->GetConstantFunction(i) == value) {
3353 return descs->GetKey(i); 3432 return descs->GetKey(i);
3354 } 3433 }
3355 } 3434 }
3356 } 3435 }
3357 return Heap::undefined_value(); 3436 return heap->undefined_value();
3358 } else { 3437 } else {
3359 return property_dictionary()->SlowReverseLookup(value); 3438 return property_dictionary()->SlowReverseLookup(value);
3360 } 3439 }
3361 } 3440 }
3362 3441
3363 3442
3364 MaybeObject* Map::CopyDropDescriptors() { 3443 MaybeObject* Map::CopyDropDescriptors() {
3444 Heap* heap = GetHeap();
3365 Object* result; 3445 Object* result;
3366 { MaybeObject* maybe_result = 3446 { MaybeObject* maybe_result =
3367 Heap::AllocateMap(instance_type(), instance_size()); 3447 heap->AllocateMap(instance_type(), instance_size());
3368 if (!maybe_result->ToObject(&result)) return maybe_result; 3448 if (!maybe_result->ToObject(&result)) return maybe_result;
3369 } 3449 }
3370 Map::cast(result)->set_prototype(prototype()); 3450 Map::cast(result)->set_prototype(prototype());
3371 Map::cast(result)->set_constructor(constructor()); 3451 Map::cast(result)->set_constructor(constructor());
3372 // Don't copy descriptors, so map transitions always remain a forest. 3452 // Don't copy descriptors, so map transitions always remain a forest.
3373 // If we retained the same descriptors we would have two maps 3453 // If we retained the same descriptors we would have two maps
3374 // pointing to the same transition which is bad because the garbage 3454 // pointing to the same transition which is bad because the garbage
3375 // collector relies on being able to reverse pointers from transitions 3455 // collector relies on being able to reverse pointers from transitions
3376 // to maps. If properties need to be retained use CopyDropTransitions. 3456 // to maps. If properties need to be retained use CopyDropTransitions.
3377 Map::cast(result)->set_instance_descriptors(Heap::empty_descriptor_array()); 3457 Map::cast(result)->set_instance_descriptors(
3458 heap->empty_descriptor_array());
3378 // Please note instance_type and instance_size are set when allocated. 3459 // Please note instance_type and instance_size are set when allocated.
3379 Map::cast(result)->set_inobject_properties(inobject_properties()); 3460 Map::cast(result)->set_inobject_properties(inobject_properties());
3380 Map::cast(result)->set_unused_property_fields(unused_property_fields()); 3461 Map::cast(result)->set_unused_property_fields(unused_property_fields());
3381 3462
3382 // If the map has pre-allocated properties always start out with a descriptor 3463 // If the map has pre-allocated properties always start out with a descriptor
3383 // array describing these properties. 3464 // array describing these properties.
3384 if (pre_allocated_property_fields() > 0) { 3465 if (pre_allocated_property_fields() > 0) {
3385 ASSERT(constructor()->IsJSFunction()); 3466 ASSERT(constructor()->IsJSFunction());
3386 JSFunction* ctor = JSFunction::cast(constructor()); 3467 JSFunction* ctor = JSFunction::cast(constructor());
3387 Object* descriptors; 3468 Object* descriptors;
3388 { MaybeObject* maybe_descriptors = 3469 { MaybeObject* maybe_descriptors =
3389 ctor->initial_map()->instance_descriptors()->RemoveTransitions(); 3470 ctor->initial_map()->instance_descriptors()->RemoveTransitions();
3390 if (!maybe_descriptors->ToObject(&descriptors)) return maybe_descriptors; 3471 if (!maybe_descriptors->ToObject(&descriptors)) return maybe_descriptors;
3391 } 3472 }
3392 Map::cast(result)->set_instance_descriptors( 3473 Map::cast(result)->set_instance_descriptors(
3393 DescriptorArray::cast(descriptors)); 3474 DescriptorArray::cast(descriptors));
3394 Map::cast(result)->set_pre_allocated_property_fields( 3475 Map::cast(result)->set_pre_allocated_property_fields(
3395 pre_allocated_property_fields()); 3476 pre_allocated_property_fields());
3396 } 3477 }
3397 Map::cast(result)->set_bit_field(bit_field()); 3478 Map::cast(result)->set_bit_field(bit_field());
3398 Map::cast(result)->set_bit_field2(bit_field2()); 3479 Map::cast(result)->set_bit_field2(bit_field2());
3399 Map::cast(result)->set_is_shared(false); 3480 Map::cast(result)->set_is_shared(false);
3400 Map::cast(result)->ClearCodeCache(); 3481 Map::cast(result)->ClearCodeCache(heap);
3401 return result; 3482 return result;
3402 } 3483 }
3403 3484
3404 3485
3405 MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode, 3486 MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode,
3406 NormalizedMapSharingMode sharing) { 3487 NormalizedMapSharingMode sharing) {
3407 int new_instance_size = instance_size(); 3488 int new_instance_size = instance_size();
3408 if (mode == CLEAR_INOBJECT_PROPERTIES) { 3489 if (mode == CLEAR_INOBJECT_PROPERTIES) {
3409 new_instance_size -= inobject_properties() * kPointerSize; 3490 new_instance_size -= inobject_properties() * kPointerSize;
3410 } 3491 }
3411 3492
3412 Object* result; 3493 Object* result;
3413 { MaybeObject* maybe_result = 3494 { MaybeObject* maybe_result =
3414 Heap::AllocateMap(instance_type(), new_instance_size); 3495 GetHeap()->AllocateMap(instance_type(), new_instance_size);
3415 if (!maybe_result->ToObject(&result)) return maybe_result; 3496 if (!maybe_result->ToObject(&result)) return maybe_result;
3416 } 3497 }
3417 3498
3418 if (mode != CLEAR_INOBJECT_PROPERTIES) { 3499 if (mode != CLEAR_INOBJECT_PROPERTIES) {
3419 Map::cast(result)->set_inobject_properties(inobject_properties()); 3500 Map::cast(result)->set_inobject_properties(inobject_properties());
3420 } 3501 }
3421 3502
3422 Map::cast(result)->set_prototype(prototype()); 3503 Map::cast(result)->set_prototype(prototype());
3423 Map::cast(result)->set_constructor(constructor()); 3504 Map::cast(result)->set_constructor(constructor());
3424 3505
(...skipping 24 matching lines...) Expand all
3449 } 3530 }
3450 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors)); 3531 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors));
3451 return new_map; 3532 return new_map;
3452 } 3533 }
3453 3534
3454 3535
3455 MaybeObject* Map::UpdateCodeCache(String* name, Code* code) { 3536 MaybeObject* Map::UpdateCodeCache(String* name, Code* code) {
3456 // Allocate the code cache if not present. 3537 // Allocate the code cache if not present.
3457 if (code_cache()->IsFixedArray()) { 3538 if (code_cache()->IsFixedArray()) {
3458 Object* result; 3539 Object* result;
3459 { MaybeObject* maybe_result = Heap::AllocateCodeCache(); 3540 { MaybeObject* maybe_result = GetHeap()->AllocateCodeCache();
3460 if (!maybe_result->ToObject(&result)) return maybe_result; 3541 if (!maybe_result->ToObject(&result)) return maybe_result;
3461 } 3542 }
3462 set_code_cache(result); 3543 set_code_cache(result);
3463 } 3544 }
3464 3545
3465 // Update the code cache. 3546 // Update the code cache.
3466 return CodeCache::cast(code_cache())->Update(name, code); 3547 return CodeCache::cast(code_cache())->Update(name, code);
3467 } 3548 }
3468 3549
3469 3550
3470 Object* Map::FindInCodeCache(String* name, Code::Flags flags) { 3551 Object* Map::FindInCodeCache(String* name, Code::Flags flags) {
3471 // Do a lookup if a code cache exists. 3552 // Do a lookup if a code cache exists.
3472 if (!code_cache()->IsFixedArray()) { 3553 if (!code_cache()->IsFixedArray()) {
3473 return CodeCache::cast(code_cache())->Lookup(name, flags); 3554 return CodeCache::cast(code_cache())->Lookup(name, flags);
3474 } else { 3555 } else {
3475 return Heap::undefined_value(); 3556 return GetHeap()->undefined_value();
3476 } 3557 }
3477 } 3558 }
3478 3559
3479 3560
3480 int Map::IndexInCodeCache(Object* name, Code* code) { 3561 int Map::IndexInCodeCache(Object* name, Code* code) {
3481 // Get the internal index if a code cache exists. 3562 // Get the internal index if a code cache exists.
3482 if (!code_cache()->IsFixedArray()) { 3563 if (!code_cache()->IsFixedArray()) {
3483 return CodeCache::cast(code_cache())->GetIndex(name, code); 3564 return CodeCache::cast(code_cache())->GetIndex(name, code);
3484 } 3565 }
3485 return -1; 3566 return -1;
3486 } 3567 }
3487 3568
3488 3569
3489 void Map::RemoveFromCodeCache(String* name, Code* code, int index) { 3570 void Map::RemoveFromCodeCache(String* name, Code* code, int index) {
3490 // No GC is supposed to happen between a call to IndexInCodeCache and 3571 // No GC is supposed to happen between a call to IndexInCodeCache and
3491 // RemoveFromCodeCache so the code cache must be there. 3572 // RemoveFromCodeCache so the code cache must be there.
3492 ASSERT(!code_cache()->IsFixedArray()); 3573 ASSERT(!code_cache()->IsFixedArray());
3493 CodeCache::cast(code_cache())->RemoveByIndex(name, code, index); 3574 CodeCache::cast(code_cache())->RemoveByIndex(name, code, index);
3494 } 3575 }
3495 3576
3496 3577
3497 void Map::TraverseTransitionTree(TraverseCallback callback, void* data) { 3578 void Map::TraverseTransitionTree(TraverseCallback callback, void* data) {
3498 Map* current = this; 3579 Map* current = this;
3499 while (current != Heap::meta_map()) { 3580 Map* meta_map = heap()->meta_map();
3581 while (current != meta_map) {
3500 DescriptorArray* d = reinterpret_cast<DescriptorArray*>( 3582 DescriptorArray* d = reinterpret_cast<DescriptorArray*>(
3501 *RawField(current, Map::kInstanceDescriptorsOffset)); 3583 *RawField(current, Map::kInstanceDescriptorsOffset));
3502 if (d == Heap::empty_descriptor_array()) { 3584 if (d == heap()->empty_descriptor_array()) {
3503 Map* prev = current->map(); 3585 Map* prev = current->map();
3504 current->set_map(Heap::meta_map()); 3586 current->set_map(meta_map);
3505 callback(current, data); 3587 callback(current, data);
3506 current = prev; 3588 current = prev;
3507 continue; 3589 continue;
3508 } 3590 }
3509 3591
3510 FixedArray* contents = reinterpret_cast<FixedArray*>( 3592 FixedArray* contents = reinterpret_cast<FixedArray*>(
3511 d->get(DescriptorArray::kContentArrayIndex)); 3593 d->get(DescriptorArray::kContentArrayIndex));
3512 Object** map_or_index_field = RawField(contents, HeapObject::kMapOffset); 3594 Object** map_or_index_field = RawField(contents, HeapObject::kMapOffset);
3513 Object* map_or_index = *map_or_index_field; 3595 Object* map_or_index = *map_or_index_field;
3514 bool map_done = true; 3596 bool map_done = true;
3515 for (int i = map_or_index->IsSmi() ? Smi::cast(map_or_index)->value() : 0; 3597 for (int i = map_or_index->IsSmi() ? Smi::cast(map_or_index)->value() : 0;
3516 i < contents->length(); 3598 i < contents->length();
3517 i += 2) { 3599 i += 2) {
3518 PropertyDetails details(Smi::cast(contents->get(i + 1))); 3600 PropertyDetails details(Smi::cast(contents->get(i + 1)));
3519 if (details.IsTransition()) { 3601 if (details.IsTransition()) {
3520 Map* next = reinterpret_cast<Map*>(contents->get(i)); 3602 Map* next = reinterpret_cast<Map*>(contents->get(i));
3521 next->set_map(current); 3603 next->set_map(current);
3522 *map_or_index_field = Smi::FromInt(i + 2); 3604 *map_or_index_field = Smi::FromInt(i + 2);
3523 current = next; 3605 current = next;
3524 map_done = false; 3606 map_done = false;
3525 break; 3607 break;
3526 } 3608 }
3527 } 3609 }
3528 if (!map_done) continue; 3610 if (!map_done) continue;
3529 *map_or_index_field = Heap::fixed_array_map(); 3611 *map_or_index_field = heap()->fixed_array_map();
3530 Map* prev = current->map(); 3612 Map* prev = current->map();
3531 current->set_map(Heap::meta_map()); 3613 current->set_map(meta_map);
3532 callback(current, data); 3614 callback(current, data);
3533 current = prev; 3615 current = prev;
3534 } 3616 }
3535 } 3617 }
3536 3618
3537 3619
3538 MaybeObject* CodeCache::Update(String* name, Code* code) { 3620 MaybeObject* CodeCache::Update(String* name, Code* code) {
3539 ASSERT(code->ic_state() == MONOMORPHIC); 3621 ASSERT(code->ic_state() == MONOMORPHIC);
3540 3622
3541 // The number of monomorphic stubs for normal load/store/call IC's can grow to 3623 // The number of monomorphic stubs for normal load/store/call IC's can grow to
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
3634 Object* CodeCache::Lookup(String* name, Code::Flags flags) { 3716 Object* CodeCache::Lookup(String* name, Code::Flags flags) {
3635 if (Code::ExtractTypeFromFlags(flags) == NORMAL) { 3717 if (Code::ExtractTypeFromFlags(flags) == NORMAL) {
3636 return LookupNormalTypeCache(name, flags); 3718 return LookupNormalTypeCache(name, flags);
3637 } else { 3719 } else {
3638 return LookupDefaultCache(name, flags); 3720 return LookupDefaultCache(name, flags);
3639 } 3721 }
3640 } 3722 }
3641 3723
3642 3724
3643 Object* CodeCache::LookupDefaultCache(String* name, Code::Flags flags) { 3725 Object* CodeCache::LookupDefaultCache(String* name, Code::Flags flags) {
3726 Heap* heap = GetHeap();
3644 FixedArray* cache = default_cache(); 3727 FixedArray* cache = default_cache();
3645 int length = cache->length(); 3728 int length = cache->length();
3646 for (int i = 0; i < length; i += kCodeCacheEntrySize) { 3729 for (int i = 0; i < length; i += kCodeCacheEntrySize) {
3647 Object* key = cache->get(i + kCodeCacheEntryNameOffset); 3730 Object* key = cache->get(i + kCodeCacheEntryNameOffset);
3648 // Skip deleted elements. 3731 // Skip deleted elements.
3649 if (key->IsNull()) continue; 3732 if (key->IsNull()) continue;
3650 if (key->IsUndefined()) return key; 3733 if (key->IsUndefined()) return key;
3651 if (name->Equals(String::cast(key))) { 3734 if (name->Equals(String::cast(key))) {
3652 Code* code = Code::cast(cache->get(i + kCodeCacheEntryCodeOffset)); 3735 Code* code = Code::cast(cache->get(i + kCodeCacheEntryCodeOffset));
3653 if (code->flags() == flags) { 3736 if (code->flags() == flags) {
3654 return code; 3737 return code;
3655 } 3738 }
3656 } 3739 }
3657 } 3740 }
3658 return Heap::undefined_value(); 3741 return heap->undefined_value();
3659 } 3742 }
3660 3743
3661 3744
3662 Object* CodeCache::LookupNormalTypeCache(String* name, Code::Flags flags) { 3745 Object* CodeCache::LookupNormalTypeCache(String* name, Code::Flags flags) {
3663 if (!normal_type_cache()->IsUndefined()) { 3746 if (!normal_type_cache()->IsUndefined()) {
3664 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); 3747 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache());
3665 return cache->Lookup(name, flags); 3748 return cache->Lookup(name, flags);
3666 } else { 3749 } else {
3667 return Heap::undefined_value(); 3750 return GetHeap()->undefined_value();
3668 } 3751 }
3669 } 3752 }
3670 3753
3671 3754
3672 int CodeCache::GetIndex(Object* name, Code* code) { 3755 int CodeCache::GetIndex(Object* name, Code* code) {
3673 if (code->type() == NORMAL) { 3756 if (code->type() == NORMAL) {
3674 if (normal_type_cache()->IsUndefined()) return -1; 3757 if (normal_type_cache()->IsUndefined()) return -1;
3675 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); 3758 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache());
3676 return cache->GetIndex(String::cast(name), code->flags()); 3759 return cache->GetIndex(String::cast(name), code->flags());
3677 } 3760 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
3739 uint32_t HashForObject(Object* obj) { 3822 uint32_t HashForObject(Object* obj) {
3740 FixedArray* pair = FixedArray::cast(obj); 3823 FixedArray* pair = FixedArray::cast(obj);
3741 String* name = String::cast(pair->get(0)); 3824 String* name = String::cast(pair->get(0));
3742 Code* code = Code::cast(pair->get(1)); 3825 Code* code = Code::cast(pair->get(1));
3743 return NameFlagsHashHelper(name, code->flags()); 3826 return NameFlagsHashHelper(name, code->flags());
3744 } 3827 }
3745 3828
3746 MUST_USE_RESULT MaybeObject* AsObject() { 3829 MUST_USE_RESULT MaybeObject* AsObject() {
3747 ASSERT(code_ != NULL); 3830 ASSERT(code_ != NULL);
3748 Object* obj; 3831 Object* obj;
3749 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(2); 3832 { MaybeObject* maybe_obj = code_->GetHeap()->AllocateFixedArray(2);
3750 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 3833 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3751 } 3834 }
3752 FixedArray* pair = FixedArray::cast(obj); 3835 FixedArray* pair = FixedArray::cast(obj);
3753 pair->set(0, name_); 3836 pair->set(0, name_);
3754 pair->set(1, code_); 3837 pair->set(1, code_);
3755 return pair; 3838 return pair;
3756 } 3839 }
3757 3840
3758 private: 3841 private:
3759 String* name_; 3842 String* name_;
3760 Code::Flags flags_; 3843 Code::Flags flags_;
3761 Code* code_; 3844 Code* code_;
3762 }; 3845 };
3763 3846
3764 3847
3765 Object* CodeCacheHashTable::Lookup(String* name, Code::Flags flags) { 3848 Object* CodeCacheHashTable::Lookup(String* name, Code::Flags flags) {
3766 CodeCacheHashTableKey key(name, flags); 3849 CodeCacheHashTableKey key(name, flags);
3767 int entry = FindEntry(&key); 3850 int entry = FindEntry(&key);
3768 if (entry == kNotFound) return Heap::undefined_value(); 3851 if (entry == kNotFound) return GetHeap()->undefined_value();
3769 return get(EntryToIndex(entry) + 1); 3852 return get(EntryToIndex(entry) + 1);
3770 } 3853 }
3771 3854
3772 3855
3773 MaybeObject* CodeCacheHashTable::Put(String* name, Code* code) { 3856 MaybeObject* CodeCacheHashTable::Put(String* name, Code* code) {
3774 CodeCacheHashTableKey key(name, code); 3857 CodeCacheHashTableKey key(name, code);
3775 Object* obj; 3858 Object* obj;
3776 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); 3859 { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
3777 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 3860 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3778 } 3861 }
(...skipping 16 matching lines...) Expand all
3795 3878
3796 int CodeCacheHashTable::GetIndex(String* name, Code::Flags flags) { 3879 int CodeCacheHashTable::GetIndex(String* name, Code::Flags flags) {
3797 CodeCacheHashTableKey key(name, flags); 3880 CodeCacheHashTableKey key(name, flags);
3798 int entry = FindEntry(&key); 3881 int entry = FindEntry(&key);
3799 return (entry == kNotFound) ? -1 : entry; 3882 return (entry == kNotFound) ? -1 : entry;
3800 } 3883 }
3801 3884
3802 3885
3803 void CodeCacheHashTable::RemoveByIndex(int index) { 3886 void CodeCacheHashTable::RemoveByIndex(int index) {
3804 ASSERT(index >= 0); 3887 ASSERT(index >= 0);
3805 set(EntryToIndex(index), Heap::null_value()); 3888 Heap* heap = GetHeap();
3806 set(EntryToIndex(index) + 1, Heap::null_value()); 3889 set(EntryToIndex(index), heap->null_value());
3890 set(EntryToIndex(index) + 1, heap->null_value());
3807 ElementRemoved(); 3891 ElementRemoved();
3808 } 3892 }
3809 3893
3810 3894
3811 static bool HasKey(FixedArray* array, Object* key) { 3895 static bool HasKey(FixedArray* array, Object* key) {
3812 int len0 = array->length(); 3896 int len0 = array->length();
3813 for (int i = 0; i < len0; i++) { 3897 for (int i = 0; i < len0; i++) {
3814 Object* element = array->get(i); 3898 Object* element = array->get(i);
3815 if (element->IsSmi() && key->IsSmi() && (element == key)) return true; 3899 if (element->IsSmi() && key->IsSmi() && (element == key)) return true;
3816 if (element->IsString() && 3900 if (element->IsString() &&
3817 key->IsString() && String::cast(element)->Equals(String::cast(key))) { 3901 key->IsString() && String::cast(element)->Equals(String::cast(key))) {
3818 return true; 3902 return true;
3819 } 3903 }
3820 } 3904 }
3821 return false; 3905 return false;
3822 } 3906 }
3823 3907
3824 3908
3825 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { 3909 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) {
3910 Heap* heap = GetHeap();
3826 ASSERT(!array->HasExternalArrayElements()); 3911 ASSERT(!array->HasExternalArrayElements());
3827 switch (array->GetElementsKind()) { 3912 switch (array->GetElementsKind()) {
3828 case JSObject::FAST_ELEMENTS: 3913 case JSObject::FAST_ELEMENTS:
3829 return UnionOfKeys(FixedArray::cast(array->elements())); 3914 return UnionOfKeys(FixedArray::cast(array->elements()));
3830 case JSObject::DICTIONARY_ELEMENTS: { 3915 case JSObject::DICTIONARY_ELEMENTS: {
3831 NumberDictionary* dict = array->element_dictionary(); 3916 NumberDictionary* dict = array->element_dictionary();
3832 int size = dict->NumberOfElements(); 3917 int size = dict->NumberOfElements();
3833 3918
3834 // Allocate a temporary fixed array. 3919 // Allocate a temporary fixed array.
3835 Object* object; 3920 Object* object;
3836 { MaybeObject* maybe_object = Heap::AllocateFixedArray(size); 3921 { MaybeObject* maybe_object = heap->AllocateFixedArray(size);
3837 if (!maybe_object->ToObject(&object)) return maybe_object; 3922 if (!maybe_object->ToObject(&object)) return maybe_object;
3838 } 3923 }
3839 FixedArray* key_array = FixedArray::cast(object); 3924 FixedArray* key_array = FixedArray::cast(object);
3840 3925
3841 int capacity = dict->Capacity(); 3926 int capacity = dict->Capacity();
3842 int pos = 0; 3927 int pos = 0;
3843 // Copy the elements from the JSArray to the temporary fixed array. 3928 // Copy the elements from the JSArray to the temporary fixed array.
3844 for (int i = 0; i < capacity; i++) { 3929 for (int i = 0; i < capacity; i++) {
3845 if (dict->IsKey(dict->KeyAt(i))) { 3930 if (dict->IsKey(dict->KeyAt(i))) {
3846 key_array->set(pos++, dict->ValueAt(i)); 3931 key_array->set(pos++, dict->ValueAt(i));
3847 } 3932 }
3848 } 3933 }
3849 // Compute the union of this and the temporary fixed array. 3934 // Compute the union of this and the temporary fixed array.
3850 return UnionOfKeys(key_array); 3935 return UnionOfKeys(key_array);
3851 } 3936 }
3852 default: 3937 default:
3853 UNREACHABLE(); 3938 UNREACHABLE();
3854 } 3939 }
3855 UNREACHABLE(); 3940 UNREACHABLE();
3856 return Heap::null_value(); // Failure case needs to "return" a value. 3941 return heap->null_value(); // Failure case needs to "return" a value.
3857 } 3942 }
3858 3943
3859 3944
3860 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) { 3945 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) {
3946 Heap* heap = GetHeap();
3861 int len0 = length(); 3947 int len0 = length();
3862 #ifdef DEBUG 3948 #ifdef DEBUG
3863 if (FLAG_enable_slow_asserts) { 3949 if (FLAG_enable_slow_asserts) {
3864 for (int i = 0; i < len0; i++) { 3950 for (int i = 0; i < len0; i++) {
3865 ASSERT(get(i)->IsString() || get(i)->IsNumber()); 3951 ASSERT(get(i)->IsString() || get(i)->IsNumber());
3866 } 3952 }
3867 } 3953 }
3868 #endif 3954 #endif
3869 int len1 = other->length(); 3955 int len1 = other->length();
3870 // Optimize if 'other' is empty. 3956 // Optimize if 'other' is empty.
3871 // We cannot optimize if 'this' is empty, as other may have holes 3957 // We cannot optimize if 'this' is empty, as other may have holes
3872 // or non keys. 3958 // or non keys.
3873 if (len1 == 0) return this; 3959 if (len1 == 0) return this;
3874 3960
3875 // Compute how many elements are not in this. 3961 // Compute how many elements are not in this.
3876 int extra = 0; 3962 int extra = 0;
3877 for (int y = 0; y < len1; y++) { 3963 for (int y = 0; y < len1; y++) {
3878 Object* value = other->get(y); 3964 Object* value = other->get(y);
3879 if (!value->IsTheHole() && !HasKey(this, value)) extra++; 3965 if (!value->IsTheHole() && !HasKey(this, value)) extra++;
3880 } 3966 }
3881 3967
3882 if (extra == 0) return this; 3968 if (extra == 0) return this;
3883 3969
3884 // Allocate the result 3970 // Allocate the result
3885 Object* obj; 3971 Object* obj;
3886 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(len0 + extra); 3972 { MaybeObject* maybe_obj = heap->AllocateFixedArray(len0 + extra);
3887 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 3973 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3888 } 3974 }
3889 // Fill in the content 3975 // Fill in the content
3890 AssertNoAllocation no_gc; 3976 AssertNoAllocation no_gc;
3891 FixedArray* result = FixedArray::cast(obj); 3977 FixedArray* result = FixedArray::cast(obj);
3892 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 3978 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
3893 for (int i = 0; i < len0; i++) { 3979 for (int i = 0; i < len0; i++) {
3894 Object* e = get(i); 3980 Object* e = get(i);
3895 ASSERT(e->IsString() || e->IsNumber()); 3981 ASSERT(e->IsString() || e->IsNumber());
3896 result->set(i, e, mode); 3982 result->set(i, e, mode);
3897 } 3983 }
3898 // Fill in the extra keys. 3984 // Fill in the extra keys.
3899 int index = 0; 3985 int index = 0;
3900 for (int y = 0; y < len1; y++) { 3986 for (int y = 0; y < len1; y++) {
3901 Object* value = other->get(y); 3987 Object* value = other->get(y);
3902 if (!value->IsTheHole() && !HasKey(this, value)) { 3988 if (!value->IsTheHole() && !HasKey(this, value)) {
3903 Object* e = other->get(y); 3989 Object* e = other->get(y);
3904 ASSERT(e->IsString() || e->IsNumber()); 3990 ASSERT(e->IsString() || e->IsNumber());
3905 result->set(len0 + index, e, mode); 3991 result->set(len0 + index, e, mode);
3906 index++; 3992 index++;
3907 } 3993 }
3908 } 3994 }
3909 ASSERT(extra == index); 3995 ASSERT(extra == index);
3910 return result; 3996 return result;
3911 } 3997 }
3912 3998
3913 3999
3914 MaybeObject* FixedArray::CopySize(int new_length) { 4000 MaybeObject* FixedArray::CopySize(int new_length) {
3915 if (new_length == 0) return Heap::empty_fixed_array(); 4001 Heap* heap = GetHeap();
4002 if (new_length == 0) return heap->empty_fixed_array();
3916 Object* obj; 4003 Object* obj;
3917 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(new_length); 4004 { MaybeObject* maybe_obj = heap->AllocateFixedArray(new_length);
3918 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 4005 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3919 } 4006 }
3920 FixedArray* result = FixedArray::cast(obj); 4007 FixedArray* result = FixedArray::cast(obj);
3921 // Copy the content 4008 // Copy the content
3922 AssertNoAllocation no_gc; 4009 AssertNoAllocation no_gc;
3923 int len = length(); 4010 int len = length();
3924 if (new_length < len) len = new_length; 4011 if (new_length < len) len = new_length;
3925 result->set_map(map()); 4012 result->set_map(map());
3926 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 4013 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
3927 for (int i = 0; i < len; i++) { 4014 for (int i = 0; i < len; i++) {
(...skipping 17 matching lines...) Expand all
3945 if (length() != other->length()) return false; 4032 if (length() != other->length()) return false;
3946 for (int i = 0 ; i < length(); ++i) { 4033 for (int i = 0 ; i < length(); ++i) {
3947 if (get(i) != other->get(i)) return false; 4034 if (get(i) != other->get(i)) return false;
3948 } 4035 }
3949 return true; 4036 return true;
3950 } 4037 }
3951 #endif 4038 #endif
3952 4039
3953 4040
3954 MaybeObject* DescriptorArray::Allocate(int number_of_descriptors) { 4041 MaybeObject* DescriptorArray::Allocate(int number_of_descriptors) {
4042 Heap* heap = Isolate::Current()->heap();
3955 if (number_of_descriptors == 0) { 4043 if (number_of_descriptors == 0) {
3956 return Heap::empty_descriptor_array(); 4044 return heap->empty_descriptor_array();
3957 } 4045 }
3958 // Allocate the array of keys. 4046 // Allocate the array of keys.
3959 Object* array; 4047 Object* array;
3960 { MaybeObject* maybe_array = 4048 { MaybeObject* maybe_array =
3961 Heap::AllocateFixedArray(ToKeyIndex(number_of_descriptors)); 4049 heap->AllocateFixedArray(ToKeyIndex(number_of_descriptors));
3962 if (!maybe_array->ToObject(&array)) return maybe_array; 4050 if (!maybe_array->ToObject(&array)) return maybe_array;
3963 } 4051 }
3964 // Do not use DescriptorArray::cast on incomplete object. 4052 // Do not use DescriptorArray::cast on incomplete object.
3965 FixedArray* result = FixedArray::cast(array); 4053 FixedArray* result = FixedArray::cast(array);
3966 4054
3967 // Allocate the content array and set it in the descriptor array. 4055 // Allocate the content array and set it in the descriptor array.
3968 { MaybeObject* maybe_array = 4056 { MaybeObject* maybe_array =
3969 Heap::AllocateFixedArray(number_of_descriptors << 1); 4057 heap->AllocateFixedArray(number_of_descriptors << 1);
3970 if (!maybe_array->ToObject(&array)) return maybe_array; 4058 if (!maybe_array->ToObject(&array)) return maybe_array;
3971 } 4059 }
3972 result->set(kContentArrayIndex, array); 4060 result->set(kContentArrayIndex, array);
3973 result->set(kEnumerationIndexIndex, 4061 result->set(kEnumerationIndexIndex,
3974 Smi::FromInt(PropertyDetails::kInitialIndex)); 4062 Smi::FromInt(PropertyDetails::kInitialIndex));
3975 return result; 4063 return result;
3976 } 4064 }
3977 4065
3978 4066
3979 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, 4067 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
4228 return number; 4316 return number;
4229 } 4317 }
4230 } 4318 }
4231 return kNotFound; 4319 return kNotFound;
4232 } 4320 }
4233 4321
4234 4322
4235 MaybeObject* DeoptimizationInputData::Allocate(int deopt_entry_count, 4323 MaybeObject* DeoptimizationInputData::Allocate(int deopt_entry_count,
4236 PretenureFlag pretenure) { 4324 PretenureFlag pretenure) {
4237 ASSERT(deopt_entry_count > 0); 4325 ASSERT(deopt_entry_count > 0);
4238 return Heap::AllocateFixedArray(LengthFor(deopt_entry_count), 4326 return HEAP->AllocateFixedArray(LengthFor(deopt_entry_count),
4239 pretenure); 4327 pretenure);
4240 } 4328 }
4241 4329
4242 4330
4243 MaybeObject* DeoptimizationOutputData::Allocate(int number_of_deopt_points, 4331 MaybeObject* DeoptimizationOutputData::Allocate(int number_of_deopt_points,
4244 PretenureFlag pretenure) { 4332 PretenureFlag pretenure) {
4245 if (number_of_deopt_points == 0) return Heap::empty_fixed_array(); 4333 if (number_of_deopt_points == 0) return HEAP->empty_fixed_array();
4246 return Heap::AllocateFixedArray(LengthOfFixedArray(number_of_deopt_points), 4334 return HEAP->AllocateFixedArray(LengthOfFixedArray(number_of_deopt_points),
4247 pretenure); 4335 pretenure);
4248 } 4336 }
4249 4337
4250 4338
4251 #ifdef DEBUG 4339 #ifdef DEBUG
4252 bool DescriptorArray::IsEqualTo(DescriptorArray* other) { 4340 bool DescriptorArray::IsEqualTo(DescriptorArray* other) {
4253 if (IsEmpty()) return other->IsEmpty(); 4341 if (IsEmpty()) return other->IsEmpty();
4254 if (other->IsEmpty()) return false; 4342 if (other->IsEmpty()) return false;
4255 if (length() != other->length()) return false; 4343 if (length() != other->length()) return false;
4256 for (int i = 0; i < length(); ++i) { 4344 for (int i = 0; i < length(); ++i) {
4257 if (get(i) != other->get(i) && i != kContentArrayIndex) return false; 4345 if (get(i) != other->get(i) && i != kContentArrayIndex) return false;
4258 } 4346 }
4259 return GetContentArray()->IsEqualTo(other->GetContentArray()); 4347 return GetContentArray()->IsEqualTo(other->GetContentArray());
4260 } 4348 }
4261 #endif 4349 #endif
4262 4350
4263 4351
4264 static StaticResource<StringInputBuffer> string_input_buffer;
4265
4266
4267 bool String::LooksValid() { 4352 bool String::LooksValid() {
4268 if (!Heap::Contains(this)) return false; 4353 if (!Isolate::Current()->heap()->Contains(this)) return false;
4269 return true; 4354 return true;
4270 } 4355 }
4271 4356
4272 4357
4273 int String::Utf8Length() { 4358 int String::Utf8Length() {
4274 if (IsAsciiRepresentation()) return length(); 4359 if (IsAsciiRepresentation()) return length();
4275 // Attempt to flatten before accessing the string. It probably 4360 // Attempt to flatten before accessing the string. It probably
4276 // doesn't make Utf8Length faster, but it is very likely that 4361 // doesn't make Utf8Length faster, but it is very likely that
4277 // the string will be accessed later (for example by WriteUtf8) 4362 // the string will be accessed later (for example by WriteUtf8)
4278 // so it's still a good idea. 4363 // so it's still a good idea.
4364 Heap* heap = GetHeap();
4279 TryFlatten(); 4365 TryFlatten();
4280 Access<StringInputBuffer> buffer(&string_input_buffer); 4366 Access<StringInputBuffer> buffer(
4367 heap->isolate()->objects_string_input_buffer());
4281 buffer->Reset(0, this); 4368 buffer->Reset(0, this);
4282 int result = 0; 4369 int result = 0;
4283 while (buffer->has_more()) 4370 while (buffer->has_more())
4284 result += unibrow::Utf8::Length(buffer->GetNext()); 4371 result += unibrow::Utf8::Length(buffer->GetNext());
4285 return result; 4372 return result;
4286 } 4373 }
4287 4374
4288 4375
4289 Vector<const char> String::ToAsciiVector() { 4376 Vector<const char> String::ToAsciiVector() {
4290 ASSERT(IsAsciiRepresentation()); 4377 ASSERT(IsAsciiRepresentation());
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4340 4427
4341 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, 4428 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls,
4342 RobustnessFlag robust_flag, 4429 RobustnessFlag robust_flag,
4343 int offset, 4430 int offset,
4344 int length, 4431 int length,
4345 int* length_return) { 4432 int* length_return) {
4346 ASSERT(NativeAllocationChecker::allocation_allowed()); 4433 ASSERT(NativeAllocationChecker::allocation_allowed());
4347 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { 4434 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) {
4348 return SmartPointer<char>(NULL); 4435 return SmartPointer<char>(NULL);
4349 } 4436 }
4437 Heap* heap = GetHeap();
4350 4438
4351 // Negative length means the to the end of the string. 4439 // Negative length means the to the end of the string.
4352 if (length < 0) length = kMaxInt - offset; 4440 if (length < 0) length = kMaxInt - offset;
4353 4441
4354 // Compute the size of the UTF-8 string. Start at the specified offset. 4442 // Compute the size of the UTF-8 string. Start at the specified offset.
4355 Access<StringInputBuffer> buffer(&string_input_buffer); 4443 Access<StringInputBuffer> buffer(
4444 heap->isolate()->objects_string_input_buffer());
4356 buffer->Reset(offset, this); 4445 buffer->Reset(offset, this);
4357 int character_position = offset; 4446 int character_position = offset;
4358 int utf8_bytes = 0; 4447 int utf8_bytes = 0;
4359 while (buffer->has_more()) { 4448 while (buffer->has_more()) {
4360 uint16_t character = buffer->GetNext(); 4449 uint16_t character = buffer->GetNext();
4361 if (character_position < offset + length) { 4450 if (character_position < offset + length) {
4362 utf8_bytes += unibrow::Utf8::Length(character); 4451 utf8_bytes += unibrow::Utf8::Length(character);
4363 } 4452 }
4364 character_position++; 4453 character_position++;
4365 } 4454 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
4415 UNREACHABLE(); 4504 UNREACHABLE();
4416 return NULL; 4505 return NULL;
4417 } 4506 }
4418 UNREACHABLE(); 4507 UNREACHABLE();
4419 return NULL; 4508 return NULL;
4420 } 4509 }
4421 4510
4422 4511
4423 SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { 4512 SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) {
4424 ASSERT(NativeAllocationChecker::allocation_allowed()); 4513 ASSERT(NativeAllocationChecker::allocation_allowed());
4425
4426 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { 4514 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) {
4427 return SmartPointer<uc16>(); 4515 return SmartPointer<uc16>();
4428 } 4516 }
4517 Heap* heap = GetHeap();
4429 4518
4430 Access<StringInputBuffer> buffer(&string_input_buffer); 4519 Access<StringInputBuffer> buffer(
4520 heap->isolate()->objects_string_input_buffer());
4431 buffer->Reset(this); 4521 buffer->Reset(this);
4432 4522
4433 uc16* result = NewArray<uc16>(length() + 1); 4523 uc16* result = NewArray<uc16>(length() + 1);
4434 4524
4435 int i = 0; 4525 int i = 0;
4436 while (buffer->has_more()) { 4526 while (buffer->has_more()) {
4437 uint16_t character = buffer->GetNext(); 4527 uint16_t character = buffer->GetNext();
4438 result[i++] = character; 4528 result[i++] = character;
4439 } 4529 }
4440 result[i] = 0; 4530 result[i] = 0;
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
4703 } 4793 }
4704 default: 4794 default:
4705 break; 4795 break;
4706 } 4796 }
4707 4797
4708 UNREACHABLE(); 4798 UNREACHABLE();
4709 return 0; 4799 return 0;
4710 } 4800 }
4711 4801
4712 4802
4713 Relocatable* Relocatable::top_ = NULL;
4714
4715
4716 void Relocatable::PostGarbageCollectionProcessing() { 4803 void Relocatable::PostGarbageCollectionProcessing() {
4717 Relocatable* current = top_; 4804 Isolate* isolate = Isolate::Current();
4805 Relocatable* current = isolate->relocatable_top();
4718 while (current != NULL) { 4806 while (current != NULL) {
4719 current->PostGarbageCollection(); 4807 current->PostGarbageCollection();
4720 current = current->prev_; 4808 current = current->prev_;
4721 } 4809 }
4722 } 4810 }
4723 4811
4724 4812
4725 // Reserve space for statics needing saving and restoring. 4813 // Reserve space for statics needing saving and restoring.
4726 int Relocatable::ArchiveSpacePerThread() { 4814 int Relocatable::ArchiveSpacePerThread() {
4727 return sizeof(top_); 4815 return sizeof(Isolate::Current()->relocatable_top());
4728 } 4816 }
4729 4817
4730 4818
4731 // Archive statics that are thread local. 4819 // Archive statics that are thread local.
4732 char* Relocatable::ArchiveState(char* to) { 4820 char* Relocatable::ArchiveState(char* to) {
4733 *reinterpret_cast<Relocatable**>(to) = top_; 4821 Isolate* isolate = Isolate::Current();
4734 top_ = NULL; 4822 *reinterpret_cast<Relocatable**>(to) = isolate->relocatable_top();
4823 isolate->set_relocatable_top(NULL);
4735 return to + ArchiveSpacePerThread(); 4824 return to + ArchiveSpacePerThread();
4736 } 4825 }
4737 4826
4738 4827
4739 // Restore statics that are thread local. 4828 // Restore statics that are thread local.
4740 char* Relocatable::RestoreState(char* from) { 4829 char* Relocatable::RestoreState(char* from) {
4741 top_ = *reinterpret_cast<Relocatable**>(from); 4830 Isolate* isolate = Isolate::Current();
4831 isolate->set_relocatable_top(*reinterpret_cast<Relocatable**>(from));
4742 return from + ArchiveSpacePerThread(); 4832 return from + ArchiveSpacePerThread();
4743 } 4833 }
4744 4834
4745 4835
4746 char* Relocatable::Iterate(ObjectVisitor* v, char* thread_storage) { 4836 char* Relocatable::Iterate(ObjectVisitor* v, char* thread_storage) {
4747 Relocatable* top = *reinterpret_cast<Relocatable**>(thread_storage); 4837 Relocatable* top = *reinterpret_cast<Relocatable**>(thread_storage);
4748 Iterate(v, top); 4838 Iterate(v, top);
4749 return thread_storage + ArchiveSpacePerThread(); 4839 return thread_storage + ArchiveSpacePerThread();
4750 } 4840 }
4751 4841
4752 4842
4753 void Relocatable::Iterate(ObjectVisitor* v) { 4843 void Relocatable::Iterate(ObjectVisitor* v) {
4754 Iterate(v, top_); 4844 Isolate* isolate = Isolate::Current();
4845 Iterate(v, isolate->relocatable_top());
4755 } 4846 }
4756 4847
4757 4848
4758 void Relocatable::Iterate(ObjectVisitor* v, Relocatable* top) { 4849 void Relocatable::Iterate(ObjectVisitor* v, Relocatable* top) {
4759 Relocatable* current = top; 4850 Relocatable* current = top;
4760 while (current != NULL) { 4851 while (current != NULL) {
4761 current->IterateInstance(v); 4852 current->IterateInstance(v);
4762 current = current->prev_; 4853 current = current->prev_;
4763 } 4854 }
4764 } 4855 }
4765 4856
4766 4857
4767 FlatStringReader::FlatStringReader(Handle<String> str) 4858 FlatStringReader::FlatStringReader(Isolate* isolate, Handle<String> str)
4768 : str_(str.location()), 4859 : Relocatable(isolate),
4860 str_(str.location()),
4769 length_(str->length()) { 4861 length_(str->length()) {
4770 PostGarbageCollection(); 4862 PostGarbageCollection();
4771 } 4863 }
4772 4864
4773 4865
4774 FlatStringReader::FlatStringReader(Vector<const char> input) 4866 FlatStringReader::FlatStringReader(Isolate* isolate, Vector<const char> input)
4775 : str_(0), 4867 : Relocatable(isolate),
4868 str_(0),
4776 is_ascii_(true), 4869 is_ascii_(true),
4777 length_(input.length()), 4870 length_(input.length()),
4778 start_(input.start()) { } 4871 start_(input.start()) { }
4779 4872
4780 4873
4781 void FlatStringReader::PostGarbageCollection() { 4874 void FlatStringReader::PostGarbageCollection() {
4782 if (str_ == NULL) return; 4875 if (str_ == NULL) return;
4783 Handle<String> str(str_); 4876 Handle<String> str(str_);
4784 ASSERT(str->IsFlat()); 4877 ASSERT(str->IsFlat());
4785 is_ascii_ = str->IsAsciiRepresentation(); 4878 is_ascii_ = str->IsAsciiRepresentation();
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
5095 // Compare the remaining characters that didn't fit into a block. 5188 // Compare the remaining characters that didn't fit into a block.
5096 for (; i < length; i++) { 5189 for (; i < length; i++) {
5097 if (a[i] != b[i]) { 5190 if (a[i] != b[i]) {
5098 return false; 5191 return false;
5099 } 5192 }
5100 } 5193 }
5101 return true; 5194 return true;
5102 } 5195 }
5103 5196
5104 5197
5105 static StringInputBuffer string_compare_buffer_b;
5106
5107
5108 template <typename IteratorA> 5198 template <typename IteratorA>
5109 static inline bool CompareStringContentsPartial(IteratorA* ia, String* b) { 5199 static inline bool CompareStringContentsPartial(Isolate* isolate,
5200 IteratorA* ia,
5201 String* b) {
5110 if (b->IsFlat()) { 5202 if (b->IsFlat()) {
5111 if (b->IsAsciiRepresentation()) { 5203 if (b->IsAsciiRepresentation()) {
5112 VectorIterator<char> ib(b->ToAsciiVector()); 5204 VectorIterator<char> ib(b->ToAsciiVector());
5113 return CompareStringContents(ia, &ib); 5205 return CompareStringContents(ia, &ib);
5114 } else { 5206 } else {
5115 VectorIterator<uc16> ib(b->ToUC16Vector()); 5207 VectorIterator<uc16> ib(b->ToUC16Vector());
5116 return CompareStringContents(ia, &ib); 5208 return CompareStringContents(ia, &ib);
5117 } 5209 }
5118 } else { 5210 } else {
5119 string_compare_buffer_b.Reset(0, b); 5211 isolate->objects_string_compare_buffer_b()->Reset(0, b);
5120 return CompareStringContents(ia, &string_compare_buffer_b); 5212 return CompareStringContents(ia,
5213 isolate->objects_string_compare_buffer_b());
5121 } 5214 }
5122 } 5215 }
5123 5216
5124 5217
5125 static StringInputBuffer string_compare_buffer_a; 5218 bool String::SlowEquals(String* other) {
5219 Heap* heap = GetHeap();
5126 5220
5127
5128 bool String::SlowEquals(String* other) {
5129 // Fast check: negative check with lengths. 5221 // Fast check: negative check with lengths.
5130 int len = length(); 5222 int len = length();
5131 if (len != other->length()) return false; 5223 if (len != other->length()) return false;
5132 if (len == 0) return true; 5224 if (len == 0) return true;
5133 5225
5134 // Fast check: if hash code is computed for both strings 5226 // Fast check: if hash code is computed for both strings
5135 // a fast negative check can be performed. 5227 // a fast negative check can be performed.
5136 if (HasHashCode() && other->HasHashCode()) { 5228 if (HasHashCode() && other->HasHashCode()) {
5137 if (Hash() != other->Hash()) return false; 5229 if (Hash() != other->Hash()) return false;
5138 } 5230 }
5139 5231
5140 // We know the strings are both non-empty. Compare the first chars 5232 // We know the strings are both non-empty. Compare the first chars
5141 // before we try to flatten the strings. 5233 // before we try to flatten the strings.
5142 if (this->Get(0) != other->Get(0)) return false; 5234 if (this->Get(0) != other->Get(0)) return false;
5143 5235
5144 String* lhs = this->TryFlattenGetString(); 5236 String* lhs = this->TryFlattenGetString();
5145 String* rhs = other->TryFlattenGetString(); 5237 String* rhs = other->TryFlattenGetString();
5146 5238
5147 if (StringShape(lhs).IsSequentialAscii() && 5239 if (StringShape(lhs).IsSequentialAscii() &&
5148 StringShape(rhs).IsSequentialAscii()) { 5240 StringShape(rhs).IsSequentialAscii()) {
5149 const char* str1 = SeqAsciiString::cast(lhs)->GetChars(); 5241 const char* str1 = SeqAsciiString::cast(lhs)->GetChars();
5150 const char* str2 = SeqAsciiString::cast(rhs)->GetChars(); 5242 const char* str2 = SeqAsciiString::cast(rhs)->GetChars();
5151 return CompareRawStringContents(Vector<const char>(str1, len), 5243 return CompareRawStringContents(Vector<const char>(str1, len),
5152 Vector<const char>(str2, len)); 5244 Vector<const char>(str2, len));
5153 } 5245 }
5154 5246
5247 Isolate* isolate = heap->isolate();
5155 if (lhs->IsFlat()) { 5248 if (lhs->IsFlat()) {
5156 if (lhs->IsAsciiRepresentation()) { 5249 if (lhs->IsAsciiRepresentation()) {
5157 Vector<const char> vec1 = lhs->ToAsciiVector(); 5250 Vector<const char> vec1 = lhs->ToAsciiVector();
5158 if (rhs->IsFlat()) { 5251 if (rhs->IsFlat()) {
5159 if (rhs->IsAsciiRepresentation()) { 5252 if (rhs->IsAsciiRepresentation()) {
5160 Vector<const char> vec2 = rhs->ToAsciiVector(); 5253 Vector<const char> vec2 = rhs->ToAsciiVector();
5161 return CompareRawStringContents(vec1, vec2); 5254 return CompareRawStringContents(vec1, vec2);
5162 } else { 5255 } else {
5163 VectorIterator<char> buf1(vec1); 5256 VectorIterator<char> buf1(vec1);
5164 VectorIterator<uc16> ib(rhs->ToUC16Vector()); 5257 VectorIterator<uc16> ib(rhs->ToUC16Vector());
5165 return CompareStringContents(&buf1, &ib); 5258 return CompareStringContents(&buf1, &ib);
5166 } 5259 }
5167 } else { 5260 } else {
5168 VectorIterator<char> buf1(vec1); 5261 VectorIterator<char> buf1(vec1);
5169 string_compare_buffer_b.Reset(0, rhs); 5262 isolate->objects_string_compare_buffer_b()->Reset(0, rhs);
5170 return CompareStringContents(&buf1, &string_compare_buffer_b); 5263 return CompareStringContents(&buf1,
5264 isolate->objects_string_compare_buffer_b());
5171 } 5265 }
5172 } else { 5266 } else {
5173 Vector<const uc16> vec1 = lhs->ToUC16Vector(); 5267 Vector<const uc16> vec1 = lhs->ToUC16Vector();
5174 if (rhs->IsFlat()) { 5268 if (rhs->IsFlat()) {
5175 if (rhs->IsAsciiRepresentation()) { 5269 if (rhs->IsAsciiRepresentation()) {
5176 VectorIterator<uc16> buf1(vec1); 5270 VectorIterator<uc16> buf1(vec1);
5177 VectorIterator<char> ib(rhs->ToAsciiVector()); 5271 VectorIterator<char> ib(rhs->ToAsciiVector());
5178 return CompareStringContents(&buf1, &ib); 5272 return CompareStringContents(&buf1, &ib);
5179 } else { 5273 } else {
5180 Vector<const uc16> vec2(rhs->ToUC16Vector()); 5274 Vector<const uc16> vec2(rhs->ToUC16Vector());
5181 return CompareRawStringContents(vec1, vec2); 5275 return CompareRawStringContents(vec1, vec2);
5182 } 5276 }
5183 } else { 5277 } else {
5184 VectorIterator<uc16> buf1(vec1); 5278 VectorIterator<uc16> buf1(vec1);
5185 string_compare_buffer_b.Reset(0, rhs); 5279 isolate->objects_string_compare_buffer_b()->Reset(0, rhs);
5186 return CompareStringContents(&buf1, &string_compare_buffer_b); 5280 return CompareStringContents(&buf1,
5281 isolate->objects_string_compare_buffer_b());
5187 } 5282 }
5188 } 5283 }
5189 } else { 5284 } else {
5190 string_compare_buffer_a.Reset(0, lhs); 5285 isolate->objects_string_compare_buffer_a()->Reset(0, lhs);
5191 return CompareStringContentsPartial(&string_compare_buffer_a, rhs); 5286 return CompareStringContentsPartial(isolate,
5287 isolate->objects_string_compare_buffer_a(), rhs);
5192 } 5288 }
5193 } 5289 }
5194 5290
5195 5291
5196 bool String::MarkAsUndetectable() { 5292 bool String::MarkAsUndetectable() {
5197 if (StringShape(this).IsSymbol()) return false; 5293 if (StringShape(this).IsSymbol()) return false;
5198 5294
5199 Map* map = this->map(); 5295 Map* map = this->map();
5200 if (map == Heap::string_map()) { 5296 Heap* heap = map->GetHeap();
5201 this->set_map(Heap::undetectable_string_map()); 5297 if (map == heap->string_map()) {
5298 this->set_map(heap->undetectable_string_map());
5202 return true; 5299 return true;
5203 } else if (map == Heap::ascii_string_map()) { 5300 } else if (map == heap->ascii_string_map()) {
5204 this->set_map(Heap::undetectable_ascii_string_map()); 5301 this->set_map(heap->undetectable_ascii_string_map());
5205 return true; 5302 return true;
5206 } 5303 }
5207 // Rest cannot be marked as undetectable 5304 // Rest cannot be marked as undetectable
5208 return false; 5305 return false;
5209 } 5306 }
5210 5307
5211 5308
5212 bool String::IsEqualTo(Vector<const char> str) { 5309 bool String::IsEqualTo(Vector<const char> str) {
5310 Isolate* isolate = GetIsolate();
5213 int slen = length(); 5311 int slen = length();
5214 Access<ScannerConstants::Utf8Decoder> 5312 Access<ScannerConstants::Utf8Decoder>
5215 decoder(ScannerConstants::utf8_decoder()); 5313 decoder(isolate->scanner_constants()->utf8_decoder());
5216 decoder->Reset(str.start(), str.length()); 5314 decoder->Reset(str.start(), str.length());
5217 int i; 5315 int i;
5218 for (i = 0; i < slen && decoder->has_more(); i++) { 5316 for (i = 0; i < slen && decoder->has_more(); i++) {
5219 uc32 r = decoder->GetNext(); 5317 uc32 r = decoder->GetNext();
5220 if (Get(i) != r) return false; 5318 if (Get(i) != r) return false;
5221 } 5319 }
5222 return i == slen && !decoder->has_more(); 5320 return i == slen && !decoder->has_more();
5223 } 5321 }
5224 5322
5225 5323
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
5367 // index. 5465 // index.
5368 while (buffer->has_more()) { 5466 while (buffer->has_more()) {
5369 hasher.AddCharacterNoIndex(buffer->GetNext()); 5467 hasher.AddCharacterNoIndex(buffer->GetNext());
5370 } 5468 }
5371 5469
5372 return hasher.GetHashField(); 5470 return hasher.GetHashField();
5373 } 5471 }
5374 5472
5375 5473
5376 MaybeObject* String::SubString(int start, int end, PretenureFlag pretenure) { 5474 MaybeObject* String::SubString(int start, int end, PretenureFlag pretenure) {
5475 Heap* heap = GetHeap();
5377 if (start == 0 && end == length()) return this; 5476 if (start == 0 && end == length()) return this;
5378 MaybeObject* result = Heap::AllocateSubString(this, start, end, pretenure); 5477 MaybeObject* result = heap->AllocateSubString(this, start, end, pretenure);
5379 return result; 5478 return result;
5380 } 5479 }
5381 5480
5382 5481
5383 void String::PrintOn(FILE* file) { 5482 void String::PrintOn(FILE* file) {
5384 int length = this->length(); 5483 int length = this->length();
5385 for (int i = 0; i < length; i++) { 5484 for (int i = 0; i < length; i++) {
5386 fprintf(file, "%c", Get(i)); 5485 fprintf(file, "%c", Get(i));
5387 } 5486 }
5388 } 5487 }
(...skipping 19 matching lines...) Expand all
5408 source_prototype == target_prototype); 5507 source_prototype == target_prototype);
5409 #endif 5508 #endif
5410 // Point target back to source. set_prototype() will not let us set 5509 // Point target back to source. set_prototype() will not let us set
5411 // the prototype to a map, as we do here. 5510 // the prototype to a map, as we do here.
5412 *RawField(target, kPrototypeOffset) = this; 5511 *RawField(target, kPrototypeOffset) = this;
5413 } 5512 }
5414 } 5513 }
5415 } 5514 }
5416 5515
5417 5516
5418 void Map::ClearNonLiveTransitions(Object* real_prototype) { 5517 void Map::ClearNonLiveTransitions(Heap* heap, Object* real_prototype) {
5419 // Live DescriptorArray objects will be marked, so we must use 5518 // Live DescriptorArray objects will be marked, so we must use
5420 // low-level accessors to get and modify their data. 5519 // low-level accessors to get and modify their data.
5421 DescriptorArray* d = reinterpret_cast<DescriptorArray*>( 5520 DescriptorArray* d = reinterpret_cast<DescriptorArray*>(
5422 *RawField(this, Map::kInstanceDescriptorsOffset)); 5521 *RawField(this, Map::kInstanceDescriptorsOffset));
5423 if (d == Heap::raw_unchecked_empty_descriptor_array()) return; 5522 if (d == heap->raw_unchecked_empty_descriptor_array()) return;
5424 Smi* NullDescriptorDetails = 5523 Smi* NullDescriptorDetails =
5425 PropertyDetails(NONE, NULL_DESCRIPTOR).AsSmi(); 5524 PropertyDetails(NONE, NULL_DESCRIPTOR).AsSmi();
5426 FixedArray* contents = reinterpret_cast<FixedArray*>( 5525 FixedArray* contents = reinterpret_cast<FixedArray*>(
5427 d->get(DescriptorArray::kContentArrayIndex)); 5526 d->get(DescriptorArray::kContentArrayIndex));
5428 ASSERT(contents->length() >= 2); 5527 ASSERT(contents->length() >= 2);
5429 for (int i = 0; i < contents->length(); i += 2) { 5528 for (int i = 0; i < contents->length(); i += 2) {
5430 // If the pair (value, details) is a map transition, 5529 // If the pair (value, details) is a map transition,
5431 // check if the target is live. If not, null the descriptor. 5530 // check if the target is live. If not, null the descriptor.
5432 // Also drop the back pointer for that map transition, so that this 5531 // Also drop the back pointer for that map transition, so that this
5433 // map is not reached again by following a back pointer from a 5532 // map is not reached again by following a back pointer from a
5434 // non-live object. 5533 // non-live object.
5435 PropertyDetails details(Smi::cast(contents->get(i + 1))); 5534 PropertyDetails details(Smi::cast(contents->get(i + 1)));
5436 if (details.type() == MAP_TRANSITION || 5535 if (details.type() == MAP_TRANSITION ||
5437 details.type() == CONSTANT_TRANSITION) { 5536 details.type() == CONSTANT_TRANSITION) {
5438 Map* target = reinterpret_cast<Map*>(contents->get(i)); 5537 Map* target = reinterpret_cast<Map*>(contents->get(i));
5439 ASSERT(target->IsHeapObject()); 5538 ASSERT(target->IsHeapObject());
5440 MarkBit map_mark = Marking::MarkBitFrom(target); 5539 MarkBit map_mark = heap->marking()->MarkBitFrom(target);
5441 if (!map_mark.Get()) { 5540 if (!map_mark.Get()) {
5442 ASSERT(target->IsMap()); 5541 ASSERT(target->IsMap());
5443 contents->set_unchecked(i + 1, NullDescriptorDetails); 5542 contents->set_unchecked(i + 1, NullDescriptorDetails);
5444 contents->set_null_unchecked(i); 5543 contents->set_null_unchecked(heap, i);
5445 ASSERT(target->prototype() == this || 5544 ASSERT(target->prototype() == this ||
5446 target->prototype() == real_prototype); 5545 target->prototype() == real_prototype);
5447 // Getter prototype() is read-only, set_prototype() has side effects. 5546 // Getter prototype() is read-only, set_prototype() has side effects.
5448 *RawField(target, Map::kPrototypeOffset) = real_prototype; 5547 *RawField(target, Map::kPrototypeOffset) = real_prototype;
5449 } 5548 }
5450 } 5549 }
5451 } 5550 }
5452 } 5551 }
5453 5552
5454 5553
5455 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) { 5554 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) {
5456 // Iterate over all fields in the body but take care in dealing with 5555 // Iterate over all fields in the body but take care in dealing with
5457 // the code entry. 5556 // the code entry.
5458 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset); 5557 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset);
5459 v->VisitCodeEntry(this->address() + kCodeEntryOffset); 5558 v->VisitCodeEntry(this->address() + kCodeEntryOffset);
5460 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size); 5559 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size);
5461 } 5560 }
5462 5561
5463 5562
5464 void JSFunction::MarkForLazyRecompilation() { 5563 void JSFunction::MarkForLazyRecompilation() {
5465 ASSERT(is_compiled() && !IsOptimized()); 5564 ASSERT(is_compiled() && !IsOptimized());
5466 ASSERT(shared()->allows_lazy_compilation() || 5565 ASSERT(shared()->allows_lazy_compilation() ||
5467 code()->optimizable()); 5566 code()->optimizable());
5468 ReplaceCode(Builtins::builtin(Builtins::LazyRecompile)); 5567 Builtins* builtins = GetIsolate()->builtins();
5568 ReplaceCode(builtins->builtin(Builtins::LazyRecompile));
5469 } 5569 }
5470 5570
5471 5571
5472 uint32_t JSFunction::SourceHash() { 5572 uint32_t JSFunction::SourceHash() {
5473 uint32_t hash = 0; 5573 uint32_t hash = 0;
5474 Object* script = shared()->script(); 5574 Object* script = shared()->script();
5475 if (!script->IsUndefined()) { 5575 if (!script->IsUndefined()) {
5476 Object* source = Script::cast(script)->source(); 5576 Object* source = Script::cast(script)->source();
5477 if (source->IsUndefined()) hash = String::cast(source)->Hash(); 5577 if (source->IsUndefined()) hash = String::cast(source)->Hash();
5478 } 5578 }
(...skipping 12 matching lines...) Expand all
5491 Code* code = shared_info->code(); 5591 Code* code = shared_info->code();
5492 if (code->kind() == Code::OPTIMIZED_FUNCTION) return true; 5592 if (code->kind() == Code::OPTIMIZED_FUNCTION) return true;
5493 // If we never ran this (unlikely) then lets try to optimize it. 5593 // If we never ran this (unlikely) then lets try to optimize it.
5494 if (code->kind() != Code::FUNCTION) return true; 5594 if (code->kind() != Code::FUNCTION) return true;
5495 return code->optimizable(); 5595 return code->optimizable();
5496 } 5596 }
5497 5597
5498 5598
5499 Object* JSFunction::SetInstancePrototype(Object* value) { 5599 Object* JSFunction::SetInstancePrototype(Object* value) {
5500 ASSERT(value->IsJSObject()); 5600 ASSERT(value->IsJSObject());
5501 5601 Heap* heap = GetHeap();
5502 if (has_initial_map()) { 5602 if (has_initial_map()) {
5503 initial_map()->set_prototype(value); 5603 initial_map()->set_prototype(value);
5504 } else { 5604 } else {
5505 // Put the value in the initial map field until an initial map is 5605 // Put the value in the initial map field until an initial map is
5506 // needed. At that point, a new initial map is created and the 5606 // needed. At that point, a new initial map is created and the
5507 // prototype is put into the initial map where it belongs. 5607 // prototype is put into the initial map where it belongs.
5508 set_prototype_or_initial_map(value); 5608 set_prototype_or_initial_map(value);
5509 } 5609 }
5510 Heap::ClearInstanceofCache(); 5610 heap->ClearInstanceofCache();
5511 return value; 5611 return value;
5512 } 5612 }
5513 5613
5514 5614
5515 MaybeObject* JSFunction::SetPrototype(Object* value) { 5615 MaybeObject* JSFunction::SetPrototype(Object* value) {
5516 ASSERT(should_have_prototype()); 5616 ASSERT(should_have_prototype());
5517 Object* construct_prototype = value; 5617 Object* construct_prototype = value;
5518 5618
5519 // If the value is not a JSObject, store the value in the map's 5619 // If the value is not a JSObject, store the value in the map's
5520 // constructor field so it can be accessed. Also, set the prototype 5620 // constructor field so it can be accessed. Also, set the prototype
5521 // used for constructing objects to the original object prototype. 5621 // used for constructing objects to the original object prototype.
5522 // See ECMA-262 13.2.2. 5622 // See ECMA-262 13.2.2.
5523 if (!value->IsJSObject()) { 5623 if (!value->IsJSObject()) {
5624 Heap* heap = GetHeap();
5524 // Copy the map so this does not affect unrelated functions. 5625 // Copy the map so this does not affect unrelated functions.
5525 // Remove map transitions because they point to maps with a 5626 // Remove map transitions because they point to maps with a
5526 // different prototype. 5627 // different prototype.
5527 Object* new_map; 5628 Object* new_map;
5528 { MaybeObject* maybe_new_map = map()->CopyDropTransitions(); 5629 { MaybeObject* maybe_new_map = map()->CopyDropTransitions();
5529 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; 5630 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
5530 } 5631 }
5531 set_map(Map::cast(new_map)); 5632 set_map(Map::cast(new_map));
5532 map()->set_constructor(value); 5633 map()->set_constructor(value);
5533 map()->set_non_instance_prototype(true); 5634 map()->set_non_instance_prototype(true);
5534 construct_prototype = 5635 construct_prototype =
5535 Top::context()->global_context()->initial_object_prototype(); 5636 heap->isolate()->context()->global_context()->
5637 initial_object_prototype();
5536 } else { 5638 } else {
5537 map()->set_non_instance_prototype(false); 5639 map()->set_non_instance_prototype(false);
5538 } 5640 }
5539 5641
5540 return SetInstancePrototype(construct_prototype); 5642 return SetInstancePrototype(construct_prototype);
5541 } 5643 }
5542 5644
5543 5645
5544 Object* JSFunction::RemovePrototype() { 5646 Object* JSFunction::RemovePrototype() {
5545 Context* global_context = context()->global_context(); 5647 Context* global_context = context()->global_context();
5546 Map* no_prototype_map = shared()->strict_mode() 5648 Map* no_prototype_map = shared()->strict_mode()
5547 ? global_context->strict_mode_function_without_prototype_map() 5649 ? global_context->strict_mode_function_without_prototype_map()
5548 : global_context->function_without_prototype_map(); 5650 : global_context->function_without_prototype_map();
5549 5651
5550 if (map() == no_prototype_map) { 5652 if (map() == no_prototype_map) {
5551 // Be idempotent. 5653 // Be idempotent.
5552 return this; 5654 return this;
5553 } 5655 }
5554 5656
5555 ASSERT(!shared()->strict_mode() || 5657 ASSERT(!shared()->strict_mode() ||
5556 map() == global_context->strict_mode_function_map()); 5658 map() == global_context->strict_mode_function_map());
5557 ASSERT(shared()->strict_mode() || map() == global_context->function_map()); 5659 ASSERT(shared()->strict_mode() || map() == global_context->function_map());
5558 5660
5559 set_map(no_prototype_map); 5661 set_map(no_prototype_map);
5560 set_prototype_or_initial_map(Heap::the_hole_value()); 5662 set_prototype_or_initial_map(GetHeap()->the_hole_value());
5561 return this; 5663 return this;
5562 } 5664 }
5563 5665
5564 5666
5565 Object* JSFunction::SetInstanceClassName(String* name) { 5667 Object* JSFunction::SetInstanceClassName(String* name) {
5566 shared()->set_instance_class_name(name); 5668 shared()->set_instance_class_name(name);
5567 return this; 5669 return this;
5568 } 5670 }
5569 5671
5570 5672
5571 void JSFunction::PrintName(FILE* out) { 5673 void JSFunction::PrintName(FILE* out) {
5572 SmartPointer<char> name = shared()->DebugName()->ToCString(); 5674 SmartPointer<char> name = shared()->DebugName()->ToCString();
5573 PrintF(out, "%s", *name); 5675 PrintF(out, "%s", *name);
5574 } 5676 }
5575 5677
5576 5678
5577 Context* JSFunction::GlobalContextFromLiterals(FixedArray* literals) { 5679 Context* JSFunction::GlobalContextFromLiterals(FixedArray* literals) {
5578 return Context::cast(literals->get(JSFunction::kLiteralGlobalContextIndex)); 5680 return Context::cast(literals->get(JSFunction::kLiteralGlobalContextIndex));
5579 } 5681 }
5580 5682
5581 5683
5582 MaybeObject* Oddball::Initialize(const char* to_string, Object* to_number) { 5684 MaybeObject* Oddball::Initialize(const char* to_string,
5685 Object* to_number,
5686 byte kind) {
5583 Object* symbol; 5687 Object* symbol;
5584 { MaybeObject* maybe_symbol = Heap::LookupAsciiSymbol(to_string); 5688 { MaybeObject* maybe_symbol =
5689 Isolate::Current()->heap()->LookupAsciiSymbol(to_string);
5585 if (!maybe_symbol->ToObject(&symbol)) return maybe_symbol; 5690 if (!maybe_symbol->ToObject(&symbol)) return maybe_symbol;
5586 } 5691 }
5587 set_to_string(String::cast(symbol)); 5692 set_to_string(String::cast(symbol));
5588 set_to_number(to_number); 5693 set_to_number(to_number);
5694 set_kind(kind);
5589 return this; 5695 return this;
5590 } 5696 }
5591 5697
5592 5698
5593 String* SharedFunctionInfo::DebugName() { 5699 String* SharedFunctionInfo::DebugName() {
5594 Object* n = name(); 5700 Object* n = name();
5595 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name(); 5701 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name();
5596 return String::cast(n); 5702 return String::cast(n);
5597 } 5703 }
5598 5704
5599 5705
5600 bool SharedFunctionInfo::HasSourceCode() { 5706 bool SharedFunctionInfo::HasSourceCode() {
5601 return !script()->IsUndefined() && 5707 return !script()->IsUndefined() &&
5602 !reinterpret_cast<Script*>(script())->source()->IsUndefined(); 5708 !reinterpret_cast<Script*>(script())->source()->IsUndefined();
5603 } 5709 }
5604 5710
5605 5711
5606 Object* SharedFunctionInfo::GetSourceCode() { 5712 Object* SharedFunctionInfo::GetSourceCode() {
5607 if (!HasSourceCode()) return Heap::undefined_value(); 5713 Isolate* isolate = GetIsolate();
5608 HandleScope scope; 5714 if (!HasSourceCode()) return isolate->heap()->undefined_value();
5715 HandleScope scope(isolate);
5609 Object* source = Script::cast(script())->source(); 5716 Object* source = Script::cast(script())->source();
5610 return *SubString(Handle<String>(String::cast(source)), 5717 return *SubString(Handle<String>(String::cast(source), isolate),
5611 start_position(), end_position()); 5718 start_position(), end_position());
5612 } 5719 }
5613 5720
5614 5721
5615 int SharedFunctionInfo::SourceSize() { 5722 int SharedFunctionInfo::SourceSize() {
5616 return end_position() - start_position(); 5723 return end_position() - start_position();
5617 } 5724 }
5618 5725
5619 5726
5620 int SharedFunctionInfo::CalculateInstanceSize() { 5727 int SharedFunctionInfo::CalculateInstanceSize() {
5621 int instance_size = 5728 int instance_size =
5622 JSObject::kHeaderSize + 5729 JSObject::kHeaderSize +
5623 expected_nof_properties() * kPointerSize; 5730 expected_nof_properties() * kPointerSize;
5624 if (instance_size > JSObject::kMaxInstanceSize) { 5731 if (instance_size > JSObject::kMaxInstanceSize) {
5625 instance_size = JSObject::kMaxInstanceSize; 5732 instance_size = JSObject::kMaxInstanceSize;
5626 } 5733 }
5627 return instance_size; 5734 return instance_size;
5628 } 5735 }
5629 5736
5630 5737
5631 int SharedFunctionInfo::CalculateInObjectProperties() { 5738 int SharedFunctionInfo::CalculateInObjectProperties() {
5632 return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize; 5739 return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize;
5633 } 5740 }
5634 5741
5635 5742
5636 bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) { 5743 bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) {
5744 Heap* heap = GetHeap();
5745
5637 // Check the basic conditions for generating inline constructor code. 5746 // Check the basic conditions for generating inline constructor code.
5638 if (!FLAG_inline_new 5747 if (!FLAG_inline_new
5639 || !has_only_simple_this_property_assignments() 5748 || !has_only_simple_this_property_assignments()
5640 || this_property_assignments_count() == 0) { 5749 || this_property_assignments_count() == 0) {
5641 return false; 5750 return false;
5642 } 5751 }
5643 5752
5644 // If the prototype is null inline constructors cause no problems. 5753 // If the prototype is null inline constructors cause no problems.
5645 if (!prototype->IsJSObject()) { 5754 if (!prototype->IsJSObject()) {
5646 ASSERT(prototype->IsNull()); 5755 ASSERT(prototype->IsNull());
5647 return true; 5756 return true;
5648 } 5757 }
5649 5758
5650 // Traverse the proposed prototype chain looking for setters for properties of 5759 // Traverse the proposed prototype chain looking for setters for properties of
5651 // the same names as are set by the inline constructor. 5760 // the same names as are set by the inline constructor.
5652 for (Object* obj = prototype; 5761 for (Object* obj = prototype;
5653 obj != Heap::null_value(); 5762 obj != heap->null_value();
5654 obj = obj->GetPrototype()) { 5763 obj = obj->GetPrototype()) {
5655 JSObject* js_object = JSObject::cast(obj); 5764 JSObject* js_object = JSObject::cast(obj);
5656 for (int i = 0; i < this_property_assignments_count(); i++) { 5765 for (int i = 0; i < this_property_assignments_count(); i++) {
5657 LookupResult result; 5766 LookupResult result;
5658 String* name = GetThisPropertyAssignmentName(i); 5767 String* name = GetThisPropertyAssignmentName(i);
5659 js_object->LocalLookupRealNamedProperty(name, &result); 5768 js_object->LocalLookupRealNamedProperty(name, &result);
5660 if (result.IsProperty() && result.type() == CALLBACKS) { 5769 if (result.IsProperty() && result.type() == CALLBACKS) {
5661 return false; 5770 return false;
5662 } 5771 }
5663 } 5772 }
(...skipping 15 matching lines...) Expand all
5679 FixedArray* assignments) { 5788 FixedArray* assignments) {
5680 set_compiler_hints(BooleanBit::set(compiler_hints(), 5789 set_compiler_hints(BooleanBit::set(compiler_hints(),
5681 kHasOnlySimpleThisPropertyAssignments, 5790 kHasOnlySimpleThisPropertyAssignments,
5682 only_simple_this_property_assignments)); 5791 only_simple_this_property_assignments));
5683 set_this_property_assignments(assignments); 5792 set_this_property_assignments(assignments);
5684 set_this_property_assignments_count(assignments->length() / 3); 5793 set_this_property_assignments_count(assignments->length() / 3);
5685 } 5794 }
5686 5795
5687 5796
5688 void SharedFunctionInfo::ClearThisPropertyAssignmentsInfo() { 5797 void SharedFunctionInfo::ClearThisPropertyAssignmentsInfo() {
5798 Heap* heap = GetHeap();
5689 set_compiler_hints(BooleanBit::set(compiler_hints(), 5799 set_compiler_hints(BooleanBit::set(compiler_hints(),
5690 kHasOnlySimpleThisPropertyAssignments, 5800 kHasOnlySimpleThisPropertyAssignments,
5691 false)); 5801 false));
5692 set_this_property_assignments(Heap::undefined_value()); 5802 set_this_property_assignments(heap->undefined_value());
5693 set_this_property_assignments_count(0); 5803 set_this_property_assignments_count(0);
5694 } 5804 }
5695 5805
5696 5806
5697 String* SharedFunctionInfo::GetThisPropertyAssignmentName(int index) { 5807 String* SharedFunctionInfo::GetThisPropertyAssignmentName(int index) {
5698 Object* obj = this_property_assignments(); 5808 Object* obj = this_property_assignments();
5699 ASSERT(obj->IsFixedArray()); 5809 ASSERT(obj->IsFixedArray());
5700 ASSERT(index < this_property_assignments_count()); 5810 ASSERT(index < this_property_assignments_count());
5701 obj = FixedArray::cast(obj)->get(index * 3); 5811 obj = FixedArray::cast(obj)->get(index * 3);
5702 ASSERT(obj->IsString()); 5812 ASSERT(obj->IsString());
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
5827 if (Serializer::enabled()) return; 5937 if (Serializer::enabled()) return;
5828 5938
5829 if (map->unused_property_fields() == 0) return; 5939 if (map->unused_property_fields() == 0) return;
5830 5940
5831 // Nonzero counter is a leftover from the previous attempt interrupted 5941 // Nonzero counter is a leftover from the previous attempt interrupted
5832 // by GC, keep it. 5942 // by GC, keep it.
5833 if (construction_count() == 0) { 5943 if (construction_count() == 0) {
5834 set_construction_count(kGenerousAllocationCount); 5944 set_construction_count(kGenerousAllocationCount);
5835 } 5945 }
5836 set_initial_map(map); 5946 set_initial_map(map);
5837 ASSERT_EQ(Builtins::builtin(Builtins::JSConstructStubGeneric), 5947 Builtins* builtins = map->heap()->isolate()->builtins();
5948 ASSERT_EQ(builtins->builtin(Builtins::JSConstructStubGeneric),
5838 construct_stub()); 5949 construct_stub());
5839 set_construct_stub(Builtins::builtin(Builtins::JSConstructStubCountdown)); 5950 set_construct_stub(builtins->builtin(Builtins::JSConstructStubCountdown));
5840 } 5951 }
5841 5952
5842 5953
5843 // Called from GC, hence reinterpret_cast and unchecked accessors. 5954 // Called from GC, hence reinterpret_cast and unchecked accessors.
5844 void SharedFunctionInfo::DetachInitialMap() { 5955 void SharedFunctionInfo::DetachInitialMap() {
5845 Map* map = reinterpret_cast<Map*>(initial_map()); 5956 Map* map = reinterpret_cast<Map*>(initial_map());
5846 5957
5847 // Make the map remember to restore the link if it survives the GC. 5958 // Make the map remember to restore the link if it survives the GC.
5848 map->set_bit_field2( 5959 map->set_bit_field2(
5849 map->bit_field2() | (1 << Map::kAttachedToSharedFunctionInfo)); 5960 map->bit_field2() | (1 << Map::kAttachedToSharedFunctionInfo));
5850 5961
5851 // Undo state changes made by StartInobjectTracking (except the 5962 // Undo state changes made by StartInobjectTracking (except the
5852 // construction_count). This way if the initial map does not survive the GC 5963 // construction_count). This way if the initial map does not survive the GC
5853 // then StartInobjectTracking will be called again the next time the 5964 // then StartInobjectTracking will be called again the next time the
5854 // constructor is called. The countdown will continue and (possibly after 5965 // constructor is called. The countdown will continue and (possibly after
5855 // several more GCs) CompleteInobjectSlackTracking will eventually be called. 5966 // several more GCs) CompleteInobjectSlackTracking will eventually be called.
5856 set_initial_map(Heap::raw_unchecked_undefined_value()); 5967 set_initial_map(map->heap()->raw_unchecked_undefined_value());
5857 ASSERT_EQ(Builtins::builtin(Builtins::JSConstructStubCountdown), 5968 Builtins* builtins = map->heap()->isolate()->builtins();
5969 ASSERT_EQ(builtins->builtin(Builtins::JSConstructStubCountdown),
5858 *RawField(this, kConstructStubOffset)); 5970 *RawField(this, kConstructStubOffset));
5859 set_construct_stub(Builtins::builtin(Builtins::JSConstructStubGeneric)); 5971 set_construct_stub(builtins->builtin(Builtins::JSConstructStubGeneric));
5860 // It is safe to clear the flag: it will be set again if the map is live. 5972 // It is safe to clear the flag: it will be set again if the map is live.
5861 set_live_objects_may_exist(false); 5973 set_live_objects_may_exist(false);
5862 } 5974 }
5863 5975
5864 5976
5865 // Called from GC, hence reinterpret_cast and unchecked accessors. 5977 // Called from GC, hence reinterpret_cast and unchecked accessors.
5866 void SharedFunctionInfo::AttachInitialMap(Map* map) { 5978 void SharedFunctionInfo::AttachInitialMap(Map* map) {
5867 map->set_bit_field2( 5979 map->set_bit_field2(
5868 map->bit_field2() & ~(1 << Map::kAttachedToSharedFunctionInfo)); 5980 map->bit_field2() & ~(1 << Map::kAttachedToSharedFunctionInfo));
5869 5981
5870 // Resume inobject slack tracking. 5982 // Resume inobject slack tracking.
5871 set_initial_map(map); 5983 set_initial_map(map);
5872 ASSERT_EQ(Builtins::builtin(Builtins::JSConstructStubGeneric), 5984 Builtins* builtins = map->heap()->isolate()->builtins();
5985 ASSERT_EQ(builtins->builtin(Builtins::JSConstructStubGeneric),
5873 *RawField(this, kConstructStubOffset)); 5986 *RawField(this, kConstructStubOffset));
5874 set_construct_stub(Builtins::builtin(Builtins::JSConstructStubCountdown)); 5987 set_construct_stub(builtins->builtin(Builtins::JSConstructStubCountdown));
5875 // The map survived the gc, so there may be objects referencing it. 5988 // The map survived the gc, so there may be objects referencing it.
5876 set_live_objects_may_exist(true); 5989 set_live_objects_may_exist(true);
5877 } 5990 }
5878 5991
5879 5992
5880 static void GetMinInobjectSlack(Map* map, void* data) { 5993 static void GetMinInobjectSlack(Map* map, void* data) {
5881 int slack = map->unused_property_fields(); 5994 int slack = map->unused_property_fields();
5882 if (*reinterpret_cast<int*>(data) > slack) { 5995 if (*reinterpret_cast<int*>(data) > slack) {
5883 *reinterpret_cast<int*>(data) = slack; 5996 *reinterpret_cast<int*>(data) = slack;
5884 } 5997 }
5885 } 5998 }
5886 5999
5887 6000
5888 static void ShrinkInstanceSize(Map* map, void* data) { 6001 static void ShrinkInstanceSize(Map* map, void* data) {
5889 int slack = *reinterpret_cast<int*>(data); 6002 int slack = *reinterpret_cast<int*>(data);
5890 map->set_inobject_properties(map->inobject_properties() - slack); 6003 map->set_inobject_properties(map->inobject_properties() - slack);
5891 map->set_unused_property_fields(map->unused_property_fields() - slack); 6004 map->set_unused_property_fields(map->unused_property_fields() - slack);
5892 map->set_instance_size(map->instance_size() - slack * kPointerSize); 6005 map->set_instance_size(map->instance_size() - slack * kPointerSize);
5893 6006
5894 // Visitor id might depend on the instance size, recalculate it. 6007 // Visitor id might depend on the instance size, recalculate it.
5895 map->set_visitor_id(StaticVisitorBase::GetVisitorId(map)); 6008 map->set_visitor_id(StaticVisitorBase::GetVisitorId(map));
5896 } 6009 }
5897 6010
5898 6011
5899 void SharedFunctionInfo::CompleteInobjectSlackTracking() { 6012 void SharedFunctionInfo::CompleteInobjectSlackTracking() {
5900 ASSERT(live_objects_may_exist() && IsInobjectSlackTrackingInProgress()); 6013 ASSERT(live_objects_may_exist() && IsInobjectSlackTrackingInProgress());
5901 Map* map = Map::cast(initial_map()); 6014 Map* map = Map::cast(initial_map());
5902 6015
5903 set_initial_map(Heap::undefined_value()); 6016 Heap* heap = map->heap();
5904 ASSERT_EQ(Builtins::builtin(Builtins::JSConstructStubCountdown), 6017 set_initial_map(heap->undefined_value());
6018 Builtins* builtins = heap->isolate()->builtins();
6019 ASSERT_EQ(builtins->builtin(Builtins::JSConstructStubCountdown),
5905 construct_stub()); 6020 construct_stub());
5906 set_construct_stub(Builtins::builtin(Builtins::JSConstructStubGeneric)); 6021 set_construct_stub(builtins->builtin(Builtins::JSConstructStubGeneric));
5907 6022
5908 int slack = map->unused_property_fields(); 6023 int slack = map->unused_property_fields();
5909 map->TraverseTransitionTree(&GetMinInobjectSlack, &slack); 6024 map->TraverseTransitionTree(&GetMinInobjectSlack, &slack);
5910 if (slack != 0) { 6025 if (slack != 0) {
5911 // Resize the initial map and all maps in its transition tree. 6026 // Resize the initial map and all maps in its transition tree.
5912 map->TraverseTransitionTree(&ShrinkInstanceSize, &slack); 6027 map->TraverseTransitionTree(&ShrinkInstanceSize, &slack);
5913 // Give the correct expected_nof_properties to initial maps created later. 6028 // Give the correct expected_nof_properties to initial maps created later.
5914 ASSERT(expected_nof_properties() >= slack); 6029 ASSERT(expected_nof_properties() >= slack);
5915 set_expected_nof_properties(expected_nof_properties() - slack); 6030 set_expected_nof_properties(expected_nof_properties() - slack);
5916 } 6031 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
5953 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && 6068 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) &&
5954 rinfo->IsPatchedDebugBreakSlotSequence())); 6069 rinfo->IsPatchedDebugBreakSlotSequence()));
5955 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); 6070 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
5956 Object* old_target = target; 6071 Object* old_target = target;
5957 VisitPointer(&target); 6072 VisitPointer(&target);
5958 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. 6073 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target.
5959 } 6074 }
5960 6075
5961 6076
5962 void Code::InvalidateRelocation() { 6077 void Code::InvalidateRelocation() {
5963 HandleScope scope; 6078 set_relocation_info(GetHeap()->empty_byte_array());
5964 set_relocation_info(Heap::empty_byte_array());
5965 } 6079 }
5966 6080
5967 6081
5968 void Code::Relocate(intptr_t delta) { 6082 void Code::Relocate(intptr_t delta) {
5969 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { 6083 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) {
5970 it.rinfo()->apply(delta); 6084 it.rinfo()->apply(delta);
5971 } 6085 }
5972 CPU::FlushICache(instruction_start(), instruction_size()); 6086 CPU::FlushICache(instruction_start(), instruction_size());
5973 } 6087 }
5974 6088
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
6400 6514
6401 PrintF("RelocInfo (size = %d)\n", relocation_size()); 6515 PrintF("RelocInfo (size = %d)\n", relocation_size());
6402 for (RelocIterator it(this); !it.done(); it.next()) it.rinfo()->Print(out); 6516 for (RelocIterator it(this); !it.done(); it.next()) it.rinfo()->Print(out);
6403 PrintF(out, "\n"); 6517 PrintF(out, "\n");
6404 } 6518 }
6405 #endif // ENABLE_DISASSEMBLER 6519 #endif // ENABLE_DISASSEMBLER
6406 6520
6407 6521
6408 MaybeObject* JSObject::SetFastElementsCapacityAndLength(int capacity, 6522 MaybeObject* JSObject::SetFastElementsCapacityAndLength(int capacity,
6409 int length) { 6523 int length) {
6524 Heap* heap = GetHeap();
6410 // We should never end in here with a pixel or external array. 6525 // We should never end in here with a pixel or external array.
6411 ASSERT(!HasExternalArrayElements()); 6526 ASSERT(!HasExternalArrayElements());
6412 6527
6413 Object* obj; 6528 Object* obj;
6414 { MaybeObject* maybe_obj = Heap::AllocateFixedArrayWithHoles(capacity); 6529 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(capacity);
6415 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 6530 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
6416 } 6531 }
6417 FixedArray* elems = FixedArray::cast(obj); 6532 FixedArray* elems = FixedArray::cast(obj);
6418 6533
6419 { MaybeObject* maybe_obj = map()->GetFastElementsMap(); 6534 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
6420 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 6535 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
6421 } 6536 }
6422 Map* new_map = Map::cast(obj); 6537 Map* new_map = Map::cast(obj);
6423 6538
6424 AssertNoAllocation no_gc; 6539 AssertNoAllocation no_gc;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
6491 } 6606 }
6492 default: 6607 default:
6493 UNREACHABLE(); 6608 UNREACHABLE();
6494 break; 6609 break;
6495 } 6610 }
6496 return this; 6611 return this;
6497 } 6612 }
6498 6613
6499 6614
6500 MaybeObject* JSArray::Initialize(int capacity) { 6615 MaybeObject* JSArray::Initialize(int capacity) {
6616 Heap* heap = GetHeap();
6501 ASSERT(capacity >= 0); 6617 ASSERT(capacity >= 0);
6502 set_length(Smi::FromInt(0)); 6618 set_length(Smi::FromInt(0));
6503 FixedArray* new_elements; 6619 FixedArray* new_elements;
6504 if (capacity == 0) { 6620 if (capacity == 0) {
6505 new_elements = Heap::empty_fixed_array(); 6621 new_elements = heap->empty_fixed_array();
6506 } else { 6622 } else {
6507 Object* obj; 6623 Object* obj;
6508 { MaybeObject* maybe_obj = Heap::AllocateFixedArrayWithHoles(capacity); 6624 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(capacity);
6509 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 6625 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
6510 } 6626 }
6511 new_elements = FixedArray::cast(obj); 6627 new_elements = FixedArray::cast(obj);
6512 } 6628 }
6513 set_elements(new_elements); 6629 set_elements(new_elements);
6514 return this; 6630 return this;
6515 } 6631 }
6516 6632
6517 6633
6518 void JSArray::Expand(int required_size) { 6634 void JSArray::Expand(int required_size) {
6519 Handle<JSArray> self(this); 6635 Handle<JSArray> self(this);
6520 Handle<FixedArray> old_backing(FixedArray::cast(elements())); 6636 Handle<FixedArray> old_backing(FixedArray::cast(elements()));
6521 int old_size = old_backing->length(); 6637 int old_size = old_backing->length();
6522 int new_size = required_size > old_size ? required_size : old_size; 6638 int new_size = required_size > old_size ? required_size : old_size;
6523 Handle<FixedArray> new_backing = Factory::NewFixedArray(new_size); 6639 Handle<FixedArray> new_backing = FACTORY->NewFixedArray(new_size);
6524 // Can't use this any more now because we may have had a GC! 6640 // Can't use this any more now because we may have had a GC!
6525 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); 6641 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i));
6526 self->SetContent(*new_backing); 6642 self->SetContent(*new_backing);
6527 } 6643 }
6528 6644
6529 6645
6530 static Failure* ArrayLengthRangeError() { 6646 static Failure* ArrayLengthRangeError(Heap* heap) {
6531 HandleScope scope; 6647 HandleScope scope;
6532 return Top::Throw(*Factory::NewRangeError("invalid_array_length", 6648 return heap->isolate()->Throw(
6533 HandleVector<Object>(NULL, 0))); 6649 *FACTORY->NewRangeError("invalid_array_length",
6650 HandleVector<Object>(NULL, 0)));
6534 } 6651 }
6535 6652
6536 6653
6537 MaybeObject* JSObject::SetElementsLength(Object* len) { 6654 MaybeObject* JSObject::SetElementsLength(Object* len) {
6655 Heap* heap = GetHeap();
6538 // We should never end in here with a pixel or external array. 6656 // We should never end in here with a pixel or external array.
6539 ASSERT(AllowsSetElementsLength()); 6657 ASSERT(AllowsSetElementsLength());
6540 6658
6541 MaybeObject* maybe_smi_length = len->ToSmi(); 6659 MaybeObject* maybe_smi_length = len->ToSmi();
6542 Object* smi_length = Smi::FromInt(0); 6660 Object* smi_length = Smi::FromInt(0);
6543 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { 6661 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) {
6544 const int value = Smi::cast(smi_length)->value(); 6662 const int value = Smi::cast(smi_length)->value();
6545 if (value < 0) return ArrayLengthRangeError(); 6663 if (value < 0) return ArrayLengthRangeError(heap);
6546 switch (GetElementsKind()) { 6664 switch (GetElementsKind()) {
6547 case FAST_ELEMENTS: { 6665 case FAST_ELEMENTS: {
6548 int old_capacity = FixedArray::cast(elements())->length(); 6666 int old_capacity = FixedArray::cast(elements())->length();
6549 if (value <= old_capacity) { 6667 if (value <= old_capacity) {
6550 if (IsJSArray()) { 6668 if (IsJSArray()) {
6551 Object* obj; 6669 Object* obj;
6552 { MaybeObject* maybe_obj = EnsureWritableFastElements(); 6670 { MaybeObject* maybe_obj = EnsureWritableFastElements();
6553 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 6671 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
6554 } 6672 }
6555 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); 6673 int old_length = FastD2I(JSArray::cast(this)->length()->Number());
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
6601 break; 6719 break;
6602 } 6720 }
6603 } 6721 }
6604 6722
6605 // General slow case. 6723 // General slow case.
6606 if (len->IsNumber()) { 6724 if (len->IsNumber()) {
6607 uint32_t length; 6725 uint32_t length;
6608 if (len->ToArrayIndex(&length)) { 6726 if (len->ToArrayIndex(&length)) {
6609 return SetSlowElements(len); 6727 return SetSlowElements(len);
6610 } else { 6728 } else {
6611 return ArrayLengthRangeError(); 6729 return ArrayLengthRangeError(heap);
6612 } 6730 }
6613 } 6731 }
6614 6732
6615 // len is not a number so make the array size one and 6733 // len is not a number so make the array size one and
6616 // set only element to len. 6734 // set only element to len.
6617 Object* obj; 6735 Object* obj;
6618 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(1); 6736 { MaybeObject* maybe_obj = heap->AllocateFixedArray(1);
6619 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 6737 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
6620 } 6738 }
6621 FixedArray::cast(obj)->set(0, len); 6739 FixedArray::cast(obj)->set(0, len);
6622 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); 6740 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1));
6623 set_elements(FixedArray::cast(obj)); 6741 set_elements(FixedArray::cast(obj));
6624 return this; 6742 return this;
6625 } 6743 }
6626 6744
6627 6745
6628 MaybeObject* JSObject::SetPrototype(Object* value, 6746 MaybeObject* JSObject::SetPrototype(Object* value,
6629 bool skip_hidden_prototypes) { 6747 bool skip_hidden_prototypes) {
6748 Heap* heap = GetHeap();
6630 // Silently ignore the change if value is not a JSObject or null. 6749 // Silently ignore the change if value is not a JSObject or null.
6631 // SpiderMonkey behaves this way. 6750 // SpiderMonkey behaves this way.
6632 if (!value->IsJSObject() && !value->IsNull()) return value; 6751 if (!value->IsJSObject() && !value->IsNull()) return value;
6633 6752
6634 // Before we can set the prototype we need to be sure 6753 // Before we can set the prototype we need to be sure
6635 // prototype cycles are prevented. 6754 // prototype cycles are prevented.
6636 // It is sufficient to validate that the receiver is not in the new prototype 6755 // It is sufficient to validate that the receiver is not in the new prototype
6637 // chain. 6756 // chain.
6638 for (Object* pt = value; pt != Heap::null_value(); pt = pt->GetPrototype()) { 6757 for (Object* pt = value; pt != heap->null_value(); pt = pt->GetPrototype()) {
6639 if (JSObject::cast(pt) == this) { 6758 if (JSObject::cast(pt) == this) {
6640 // Cycle detected. 6759 // Cycle detected.
6641 HandleScope scope; 6760 HandleScope scope;
6642 return Top::Throw(*Factory::NewError("cyclic_proto", 6761 return heap->isolate()->Throw(
6643 HandleVector<Object>(NULL, 0))); 6762 *FACTORY->NewError("cyclic_proto", HandleVector<Object>(NULL, 0)));
6644 } 6763 }
6645 } 6764 }
6646 6765
6647 JSObject* real_receiver = this; 6766 JSObject* real_receiver = this;
6648 6767
6649 if (skip_hidden_prototypes) { 6768 if (skip_hidden_prototypes) {
6650 // Find the first object in the chain whose prototype object is not 6769 // Find the first object in the chain whose prototype object is not
6651 // hidden and set the new prototype on that object. 6770 // hidden and set the new prototype on that object.
6652 Object* current_proto = real_receiver->GetPrototype(); 6771 Object* current_proto = real_receiver->GetPrototype();
6653 while (current_proto->IsJSObject() && 6772 while (current_proto->IsJSObject() &&
6654 JSObject::cast(current_proto)->map()->is_hidden_prototype()) { 6773 JSObject::cast(current_proto)->map()->is_hidden_prototype()) {
6655 real_receiver = JSObject::cast(current_proto); 6774 real_receiver = JSObject::cast(current_proto);
6656 current_proto = current_proto->GetPrototype(); 6775 current_proto = current_proto->GetPrototype();
6657 } 6776 }
6658 } 6777 }
6659 6778
6660 // Set the new prototype of the object. 6779 // Set the new prototype of the object.
6661 Object* new_map; 6780 Object* new_map;
6662 { MaybeObject* maybe_new_map = real_receiver->map()->CopyDropTransitions(); 6781 { MaybeObject* maybe_new_map = real_receiver->map()->CopyDropTransitions();
6663 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; 6782 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
6664 } 6783 }
6665 Map::cast(new_map)->set_prototype(value); 6784 Map::cast(new_map)->set_prototype(value);
6666 real_receiver->set_map(Map::cast(new_map)); 6785 real_receiver->set_map(Map::cast(new_map));
6667 6786
6668 Heap::ClearInstanceofCache(); 6787 heap->ClearInstanceofCache();
6669 6788
6670 return value; 6789 return value;
6671 } 6790 }
6672 6791
6673 6792
6674 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) { 6793 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) {
6675 switch (GetElementsKind()) { 6794 switch (GetElementsKind()) {
6676 case FAST_ELEMENTS: { 6795 case FAST_ELEMENTS: {
6677 uint32_t length = IsJSArray() ? 6796 uint32_t length = IsJSArray() ?
6678 static_cast<uint32_t> 6797 static_cast<uint32_t>
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
6713 } 6832 }
6714 default: 6833 default:
6715 UNREACHABLE(); 6834 UNREACHABLE();
6716 break; 6835 break;
6717 } 6836 }
6718 6837
6719 // Handle [] on String objects. 6838 // Handle [] on String objects.
6720 if (this->IsStringObjectWithCharacterAt(index)) return true; 6839 if (this->IsStringObjectWithCharacterAt(index)) return true;
6721 6840
6722 Object* pt = GetPrototype(); 6841 Object* pt = GetPrototype();
6723 if (pt == Heap::null_value()) return false; 6842 if (pt->IsNull()) return false;
6724 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); 6843 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index);
6725 } 6844 }
6726 6845
6727 6846
6728 bool JSObject::HasElementWithInterceptor(JSObject* receiver, uint32_t index) { 6847 bool JSObject::HasElementWithInterceptor(JSObject* receiver, uint32_t index) {
6848 Isolate* isolate = GetIsolate();
6729 // Make sure that the top context does not change when doing 6849 // Make sure that the top context does not change when doing
6730 // callbacks or interceptor calls. 6850 // callbacks or interceptor calls.
6731 AssertNoContextChange ncc; 6851 AssertNoContextChange ncc;
6732 HandleScope scope; 6852 HandleScope scope(isolate);
6733 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); 6853 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
6734 Handle<JSObject> receiver_handle(receiver); 6854 Handle<JSObject> receiver_handle(receiver);
6735 Handle<JSObject> holder_handle(this); 6855 Handle<JSObject> holder_handle(this);
6736 CustomArguments args(interceptor->data(), receiver, this); 6856 CustomArguments args(isolate, interceptor->data(), receiver, this);
6737 v8::AccessorInfo info(args.end()); 6857 v8::AccessorInfo info(args.end());
6738 if (!interceptor->query()->IsUndefined()) { 6858 if (!interceptor->query()->IsUndefined()) {
6739 v8::IndexedPropertyQuery query = 6859 v8::IndexedPropertyQuery query =
6740 v8::ToCData<v8::IndexedPropertyQuery>(interceptor->query()); 6860 v8::ToCData<v8::IndexedPropertyQuery>(interceptor->query());
6741 LOG(ApiIndexedPropertyAccess("interceptor-indexed-has", this, index)); 6861 LOG(isolate,
6862 ApiIndexedPropertyAccess("interceptor-indexed-has", this, index));
6742 v8::Handle<v8::Integer> result; 6863 v8::Handle<v8::Integer> result;
6743 { 6864 {
6744 // Leaving JavaScript. 6865 // Leaving JavaScript.
6745 VMState state(EXTERNAL); 6866 VMState state(isolate, EXTERNAL);
6746 result = query(index, info); 6867 result = query(index, info);
6747 } 6868 }
6748 if (!result.IsEmpty()) { 6869 if (!result.IsEmpty()) {
6749 ASSERT(result->IsInt32()); 6870 ASSERT(result->IsInt32());
6750 return true; // absence of property is signaled by empty handle. 6871 return true; // absence of property is signaled by empty handle.
6751 } 6872 }
6752 } else if (!interceptor->getter()->IsUndefined()) { 6873 } else if (!interceptor->getter()->IsUndefined()) {
6753 v8::IndexedPropertyGetter getter = 6874 v8::IndexedPropertyGetter getter =
6754 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter()); 6875 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter());
6755 LOG(ApiIndexedPropertyAccess("interceptor-indexed-has-get", this, index)); 6876 LOG(isolate,
6877 ApiIndexedPropertyAccess("interceptor-indexed-has-get", this, index));
6756 v8::Handle<v8::Value> result; 6878 v8::Handle<v8::Value> result;
6757 { 6879 {
6758 // Leaving JavaScript. 6880 // Leaving JavaScript.
6759 VMState state(EXTERNAL); 6881 VMState state(isolate, EXTERNAL);
6760 result = getter(index, info); 6882 result = getter(index, info);
6761 } 6883 }
6762 if (!result.IsEmpty()) return true; 6884 if (!result.IsEmpty()) return true;
6763 } 6885 }
6764 return holder_handle->HasElementPostInterceptor(*receiver_handle, index); 6886 return holder_handle->HasElementPostInterceptor(*receiver_handle, index);
6765 } 6887 }
6766 6888
6767 6889
6768 JSObject::LocalElementType JSObject::HasLocalElement(uint32_t index) { 6890 JSObject::LocalElementType JSObject::HasLocalElement(uint32_t index) {
6891 Heap* heap = GetHeap();
6892
6769 // Check access rights if needed. 6893 // Check access rights if needed.
6770 if (IsAccessCheckNeeded() && 6894 if (IsAccessCheckNeeded() &&
6771 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) { 6895 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) {
6772 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); 6896 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
6773 return UNDEFINED_ELEMENT; 6897 return UNDEFINED_ELEMENT;
6774 } 6898 }
6775 6899
6776 if (IsJSGlobalProxy()) { 6900 if (IsJSGlobalProxy()) {
6777 Object* proto = GetPrototype(); 6901 Object* proto = GetPrototype();
6778 if (proto->IsNull()) return UNDEFINED_ELEMENT; 6902 if (proto->IsNull()) return UNDEFINED_ELEMENT;
6779 ASSERT(proto->IsJSGlobalObject()); 6903 ASSERT(proto->IsJSGlobalObject());
6780 return JSObject::cast(proto)->HasLocalElement(index); 6904 return JSObject::cast(proto)->HasLocalElement(index);
6781 } 6905 }
6782 6906
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
6829 default: 6953 default:
6830 UNREACHABLE(); 6954 UNREACHABLE();
6831 break; 6955 break;
6832 } 6956 }
6833 6957
6834 return UNDEFINED_ELEMENT; 6958 return UNDEFINED_ELEMENT;
6835 } 6959 }
6836 6960
6837 6961
6838 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) { 6962 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) {
6963 Heap* heap = GetHeap();
6964
6839 // Check access rights if needed. 6965 // Check access rights if needed.
6840 if (IsAccessCheckNeeded() && 6966 if (IsAccessCheckNeeded() &&
6841 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) { 6967 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) {
6842 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); 6968 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
6843 return false; 6969 return false;
6844 } 6970 }
6845 6971
6846 // Check for lookup interceptor 6972 // Check for lookup interceptor
6847 if (HasIndexedInterceptor()) { 6973 if (HasIndexedInterceptor()) {
6848 return HasElementWithInterceptor(receiver, index); 6974 return HasElementWithInterceptor(receiver, index);
6849 } 6975 }
6850 6976
6851 switch (GetElementsKind()) { 6977 switch (GetElementsKind()) {
6852 case FAST_ELEMENTS: { 6978 case FAST_ELEMENTS: {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
6887 } 7013 }
6888 default: 7014 default:
6889 UNREACHABLE(); 7015 UNREACHABLE();
6890 break; 7016 break;
6891 } 7017 }
6892 7018
6893 // Handle [] on String objects. 7019 // Handle [] on String objects.
6894 if (this->IsStringObjectWithCharacterAt(index)) return true; 7020 if (this->IsStringObjectWithCharacterAt(index)) return true;
6895 7021
6896 Object* pt = GetPrototype(); 7022 Object* pt = GetPrototype();
6897 if (pt == Heap::null_value()) return false; 7023 if (pt->IsNull()) return false;
6898 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); 7024 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index);
6899 } 7025 }
6900 7026
6901 7027
6902 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, 7028 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index,
6903 Object* value, 7029 Object* value,
6904 StrictModeFlag strict_mode, 7030 StrictModeFlag strict_mode,
6905 bool check_prototype) { 7031 bool check_prototype) {
7032 Isolate* isolate = GetIsolate();
6906 // Make sure that the top context does not change when doing 7033 // Make sure that the top context does not change when doing
6907 // callbacks or interceptor calls. 7034 // callbacks or interceptor calls.
6908 AssertNoContextChange ncc; 7035 AssertNoContextChange ncc;
6909 HandleScope scope; 7036 HandleScope scope(isolate);
6910 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); 7037 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
6911 Handle<JSObject> this_handle(this); 7038 Handle<JSObject> this_handle(this);
6912 Handle<Object> value_handle(value); 7039 Handle<Object> value_handle(value, isolate);
6913 if (!interceptor->setter()->IsUndefined()) { 7040 if (!interceptor->setter()->IsUndefined()) {
6914 v8::IndexedPropertySetter setter = 7041 v8::IndexedPropertySetter setter =
6915 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); 7042 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter());
6916 LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); 7043 LOG(isolate,
6917 CustomArguments args(interceptor->data(), this, this); 7044 ApiIndexedPropertyAccess("interceptor-indexed-set", this, index));
7045 CustomArguments args(isolate, interceptor->data(), this, this);
6918 v8::AccessorInfo info(args.end()); 7046 v8::AccessorInfo info(args.end());
6919 v8::Handle<v8::Value> result; 7047 v8::Handle<v8::Value> result;
6920 { 7048 {
6921 // Leaving JavaScript. 7049 // Leaving JavaScript.
6922 VMState state(EXTERNAL); 7050 VMState state(isolate, EXTERNAL);
6923 result = setter(index, v8::Utils::ToLocal(value_handle), info); 7051 result = setter(index, v8::Utils::ToLocal(value_handle), info);
6924 } 7052 }
6925 RETURN_IF_SCHEDULED_EXCEPTION(); 7053 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
6926 if (!result.IsEmpty()) return *value_handle; 7054 if (!result.IsEmpty()) return *value_handle;
6927 } 7055 }
6928 MaybeObject* raw_result = 7056 MaybeObject* raw_result =
6929 this_handle->SetElementWithoutInterceptor(index, 7057 this_handle->SetElementWithoutInterceptor(index,
6930 *value_handle, 7058 *value_handle,
6931 strict_mode, 7059 strict_mode,
6932 check_prototype); 7060 check_prototype);
6933 RETURN_IF_SCHEDULED_EXCEPTION(); 7061 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
6934 return raw_result; 7062 return raw_result;
6935 } 7063 }
6936 7064
6937 7065
6938 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, 7066 MaybeObject* JSObject::GetElementWithCallback(Object* receiver,
6939 Object* structure, 7067 Object* structure,
6940 uint32_t index, 7068 uint32_t index,
6941 Object* holder) { 7069 Object* holder) {
7070 Isolate* isolate = GetIsolate();
6942 ASSERT(!structure->IsProxy()); 7071 ASSERT(!structure->IsProxy());
6943 7072
6944 // api style callbacks. 7073 // api style callbacks.
6945 if (structure->IsAccessorInfo()) { 7074 if (structure->IsAccessorInfo()) {
6946 AccessorInfo* data = AccessorInfo::cast(structure); 7075 AccessorInfo* data = AccessorInfo::cast(structure);
6947 Object* fun_obj = data->getter(); 7076 Object* fun_obj = data->getter();
6948 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); 7077 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj);
6949 HandleScope scope; 7078 HandleScope scope(isolate);
6950 Handle<JSObject> self(JSObject::cast(receiver)); 7079 Handle<JSObject> self(JSObject::cast(receiver));
6951 Handle<JSObject> holder_handle(JSObject::cast(holder)); 7080 Handle<JSObject> holder_handle(JSObject::cast(holder));
6952 Handle<Object> number = Factory::NewNumberFromUint(index); 7081 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
6953 Handle<String> key(Factory::NumberToString(number)); 7082 Handle<String> key(isolate->factory()->NumberToString(number));
6954 LOG(ApiNamedPropertyAccess("load", *self, *key)); 7083 LOG(isolate, ApiNamedPropertyAccess("load", *self, *key));
6955 CustomArguments args(data->data(), *self, *holder_handle); 7084 CustomArguments args(isolate, data->data(), *self, *holder_handle);
6956 v8::AccessorInfo info(args.end()); 7085 v8::AccessorInfo info(args.end());
6957 v8::Handle<v8::Value> result; 7086 v8::Handle<v8::Value> result;
6958 { 7087 {
6959 // Leaving JavaScript. 7088 // Leaving JavaScript.
6960 VMState state(EXTERNAL); 7089 VMState state(isolate, EXTERNAL);
6961 result = call_fun(v8::Utils::ToLocal(key), info); 7090 result = call_fun(v8::Utils::ToLocal(key), info);
6962 } 7091 }
6963 RETURN_IF_SCHEDULED_EXCEPTION(); 7092 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
6964 if (result.IsEmpty()) return Heap::undefined_value(); 7093 if (result.IsEmpty()) return isolate->heap()->undefined_value();
6965 return *v8::Utils::OpenHandle(*result); 7094 return *v8::Utils::OpenHandle(*result);
6966 } 7095 }
6967 7096
6968 // __defineGetter__ callback 7097 // __defineGetter__ callback
6969 if (structure->IsFixedArray()) { 7098 if (structure->IsFixedArray()) {
6970 Object* getter = FixedArray::cast(structure)->get(kGetterIndex); 7099 Object* getter = FixedArray::cast(structure)->get(kGetterIndex);
6971 if (getter->IsJSFunction()) { 7100 if (getter->IsJSFunction()) {
6972 return Object::GetPropertyWithDefinedGetter(receiver, 7101 return Object::GetPropertyWithDefinedGetter(receiver,
6973 JSFunction::cast(getter)); 7102 JSFunction::cast(getter));
6974 } 7103 }
6975 // Getter is not a function. 7104 // Getter is not a function.
6976 return Heap::undefined_value(); 7105 return isolate->heap()->undefined_value();
6977 } 7106 }
6978 7107
6979 UNREACHABLE(); 7108 UNREACHABLE();
6980 return NULL; 7109 return NULL;
6981 } 7110 }
6982 7111
6983 7112
6984 MaybeObject* JSObject::SetElementWithCallback(Object* structure, 7113 MaybeObject* JSObject::SetElementWithCallback(Object* structure,
6985 uint32_t index, 7114 uint32_t index,
6986 Object* value, 7115 Object* value,
6987 JSObject* holder) { 7116 JSObject* holder) {
6988 HandleScope scope; 7117 Isolate* isolate = GetIsolate();
7118 HandleScope scope(isolate);
6989 7119
6990 // We should never get here to initialize a const with the hole 7120 // We should never get here to initialize a const with the hole
6991 // value since a const declaration would conflict with the setter. 7121 // value since a const declaration would conflict with the setter.
6992 ASSERT(!value->IsTheHole()); 7122 ASSERT(!value->IsTheHole());
6993 Handle<Object> value_handle(value); 7123 Handle<Object> value_handle(value, isolate);
6994 7124
6995 // To accommodate both the old and the new api we switch on the 7125 // To accommodate both the old and the new api we switch on the
6996 // data structure used to store the callbacks. Eventually proxy 7126 // data structure used to store the callbacks. Eventually proxy
6997 // callbacks should be phased out. 7127 // callbacks should be phased out.
6998 ASSERT(!structure->IsProxy()); 7128 ASSERT(!structure->IsProxy());
6999 7129
7000 if (structure->IsAccessorInfo()) { 7130 if (structure->IsAccessorInfo()) {
7001 // api style callbacks 7131 // api style callbacks
7002 AccessorInfo* data = AccessorInfo::cast(structure); 7132 AccessorInfo* data = AccessorInfo::cast(structure);
7003 Object* call_obj = data->setter(); 7133 Object* call_obj = data->setter();
7004 v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj); 7134 v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj);
7005 if (call_fun == NULL) return value; 7135 if (call_fun == NULL) return value;
7006 Handle<Object> number = Factory::NewNumberFromUint(index); 7136 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
7007 Handle<String> key(Factory::NumberToString(number)); 7137 Handle<String> key(isolate->factory()->NumberToString(number));
7008 LOG(ApiNamedPropertyAccess("store", this, *key)); 7138 LOG(isolate, ApiNamedPropertyAccess("store", this, *key));
7009 CustomArguments args(data->data(), this, JSObject::cast(holder)); 7139 CustomArguments args(isolate, data->data(), this, JSObject::cast(holder));
7010 v8::AccessorInfo info(args.end()); 7140 v8::AccessorInfo info(args.end());
7011 { 7141 {
7012 // Leaving JavaScript. 7142 // Leaving JavaScript.
7013 VMState state(EXTERNAL); 7143 VMState state(isolate, EXTERNAL);
7014 call_fun(v8::Utils::ToLocal(key), 7144 call_fun(v8::Utils::ToLocal(key),
7015 v8::Utils::ToLocal(value_handle), 7145 v8::Utils::ToLocal(value_handle),
7016 info); 7146 info);
7017 } 7147 }
7018 RETURN_IF_SCHEDULED_EXCEPTION(); 7148 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
7019 return *value_handle; 7149 return *value_handle;
7020 } 7150 }
7021 7151
7022 if (structure->IsFixedArray()) { 7152 if (structure->IsFixedArray()) {
7023 Object* setter = FixedArray::cast(structure)->get(kSetterIndex); 7153 Object* setter = FixedArray::cast(structure)->get(kSetterIndex);
7024 if (setter->IsJSFunction()) { 7154 if (setter->IsJSFunction()) {
7025 return SetPropertyWithDefinedSetter(JSFunction::cast(setter), value); 7155 return SetPropertyWithDefinedSetter(JSFunction::cast(setter), value);
7026 } else { 7156 } else {
7027 Handle<Object> holder_handle(holder); 7157 Handle<Object> holder_handle(holder, isolate);
7028 Handle<Object> key(Factory::NewNumberFromUint(index)); 7158 Handle<Object> key(isolate->factory()->NewNumberFromUint(index));
7029 Handle<Object> args[2] = { key, holder_handle }; 7159 Handle<Object> args[2] = { key, holder_handle };
7030 return Top::Throw(*Factory::NewTypeError("no_setter_in_callback", 7160 return isolate->Throw(
7031 HandleVector(args, 2))); 7161 *isolate->factory()->NewTypeError("no_setter_in_callback",
7162 HandleVector(args, 2)));
7032 } 7163 }
7033 } 7164 }
7034 7165
7035 UNREACHABLE(); 7166 UNREACHABLE();
7036 return NULL; 7167 return NULL;
7037 } 7168 }
7038 7169
7039 7170
7040 // Adding n elements in fast case is O(n*n). 7171 // Adding n elements in fast case is O(n*n).
7041 // Note: revisit design to have dual undefined values to capture absent 7172 // Note: revisit design to have dual undefined values to capture absent
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
7100 } 7231 }
7101 ASSERT(HasDictionaryElements()); 7232 ASSERT(HasDictionaryElements());
7102 return SetElement(index, value, strict_mode, check_prototype); 7233 return SetElement(index, value, strict_mode, check_prototype);
7103 } 7234 }
7104 7235
7105 7236
7106 MaybeObject* JSObject::SetElement(uint32_t index, 7237 MaybeObject* JSObject::SetElement(uint32_t index,
7107 Object* value, 7238 Object* value,
7108 StrictModeFlag strict_mode, 7239 StrictModeFlag strict_mode,
7109 bool check_prototype) { 7240 bool check_prototype) {
7241 Heap* heap = GetHeap();
7110 // Check access rights if needed. 7242 // Check access rights if needed.
7111 if (IsAccessCheckNeeded() && 7243 if (IsAccessCheckNeeded() &&
7112 !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) { 7244 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) {
7113 HandleScope scope; 7245 HandleScope scope;
7114 Handle<Object> value_handle(value); 7246 Handle<Object> value_handle(value);
7115 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); 7247 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET);
7116 return *value_handle; 7248 return *value_handle;
7117 } 7249 }
7118 7250
7119 if (IsJSGlobalProxy()) { 7251 if (IsJSGlobalProxy()) {
7120 Object* proto = GetPrototype(); 7252 Object* proto = GetPrototype();
7121 if (proto->IsNull()) return value; 7253 if (proto->IsNull()) return value;
7122 ASSERT(proto->IsJSGlobalObject()); 7254 ASSERT(proto->IsJSGlobalObject());
7123 return JSObject::cast(proto)->SetElement(index, 7255 return JSObject::cast(proto)->SetElement(index,
7124 value, 7256 value,
7125 strict_mode, 7257 strict_mode,
(...skipping 12 matching lines...) Expand all
7138 value, 7270 value,
7139 strict_mode, 7271 strict_mode,
7140 check_prototype); 7272 check_prototype);
7141 } 7273 }
7142 7274
7143 7275
7144 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, 7276 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index,
7145 Object* value, 7277 Object* value,
7146 StrictModeFlag strict_mode, 7278 StrictModeFlag strict_mode,
7147 bool check_prototype) { 7279 bool check_prototype) {
7280 Isolate* isolate = GetIsolate();
7148 switch (GetElementsKind()) { 7281 switch (GetElementsKind()) {
7149 case FAST_ELEMENTS: 7282 case FAST_ELEMENTS:
7150 // Fast case. 7283 // Fast case.
7151 return SetFastElement(index, value, strict_mode, check_prototype); 7284 return SetFastElement(index, value, strict_mode, check_prototype);
7152 case EXTERNAL_PIXEL_ELEMENTS: { 7285 case EXTERNAL_PIXEL_ELEMENTS: {
7153 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); 7286 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
7154 return pixels->SetValue(index, value); 7287 return pixels->SetValue(index, value);
7155 } 7288 }
7156 case EXTERNAL_BYTE_ELEMENTS: { 7289 case EXTERNAL_BYTE_ELEMENTS: {
7157 ExternalByteArray* array = ExternalByteArray::cast(elements()); 7290 ExternalByteArray* array = ExternalByteArray::cast(elements());
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
7193 if (entry != NumberDictionary::kNotFound) { 7326 if (entry != NumberDictionary::kNotFound) {
7194 Object* element = dictionary->ValueAt(entry); 7327 Object* element = dictionary->ValueAt(entry);
7195 PropertyDetails details = dictionary->DetailsAt(entry); 7328 PropertyDetails details = dictionary->DetailsAt(entry);
7196 if (details.type() == CALLBACKS) { 7329 if (details.type() == CALLBACKS) {
7197 return SetElementWithCallback(element, index, value, this); 7330 return SetElementWithCallback(element, index, value, this);
7198 } else { 7331 } else {
7199 dictionary->UpdateMaxNumberKey(index); 7332 dictionary->UpdateMaxNumberKey(index);
7200 // If put fails instrict mode, throw exception. 7333 // If put fails instrict mode, throw exception.
7201 if (!dictionary->ValueAtPut(entry, value) && 7334 if (!dictionary->ValueAtPut(entry, value) &&
7202 strict_mode == kStrictMode) { 7335 strict_mode == kStrictMode) {
7203 Handle<Object> number(Factory::NewNumberFromUint(index)); 7336 Handle<Object> number(isolate->factory()->NewNumberFromUint(index));
7204 Handle<Object> holder(this); 7337 Handle<Object> holder(this);
7205 Handle<Object> args[2] = { number, holder }; 7338 Handle<Object> args[2] = { number, holder };
7206 return Top::Throw( 7339 return isolate->Throw(
7207 *Factory::NewTypeError("strict_read_only_property", 7340 *isolate->factory()->NewTypeError("strict_read_only_property",
7208 HandleVector(args, 2))); 7341 HandleVector(args, 2)));
7209 } 7342 }
7210 } 7343 }
7211 } else { 7344 } else {
7212 // Index not already used. Look for an accessor in the prototype chain. 7345 // Index not already used. Look for an accessor in the prototype chain.
7213 if (check_prototype) { 7346 if (check_prototype) {
7214 bool found; 7347 bool found;
7215 MaybeObject* result = 7348 MaybeObject* result =
7216 // Strict mode not needed. No-setter case already handled. 7349 // Strict mode not needed. No-setter case already handled.
7217 SetElementWithCallbackSetterInPrototypes(index, value, &found); 7350 SetElementWithCallbackSetterInPrototypes(index, value, &found);
7218 if (found) return result; 7351 if (found) return result;
7219 } 7352 }
7220 // When we set the is_extensible flag to false we always force 7353 // When we set the is_extensible flag to false we always force
7221 // the element into dictionary mode (and force them to stay there). 7354 // the element into dictionary mode (and force them to stay there).
7222 if (!map()->is_extensible()) { 7355 if (!map()->is_extensible()) {
7223 Handle<Object> number(Factory::NewNumberFromUint(index)); 7356 Handle<Object> number(isolate->factory()->NewNumberFromUint(index));
7224 Handle<String> index_string(Factory::NumberToString(number)); 7357 Handle<String> index_string(
7358 isolate->factory()->NumberToString(number));
7225 Handle<Object> args[1] = { index_string }; 7359 Handle<Object> args[1] = { index_string };
7226 return Top::Throw(*Factory::NewTypeError("object_not_extensible", 7360 return isolate->Throw(
7227 HandleVector(args, 1))); 7361 *isolate->factory()->NewTypeError("object_not_extensible",
7362 HandleVector(args, 1)));
7228 } 7363 }
7229 Object* result; 7364 Object* result;
7230 { MaybeObject* maybe_result = dictionary->AtNumberPut(index, value); 7365 { MaybeObject* maybe_result = dictionary->AtNumberPut(index, value);
7231 if (!maybe_result->ToObject(&result)) return maybe_result; 7366 if (!maybe_result->ToObject(&result)) return maybe_result;
7232 } 7367 }
7233 if (elms != FixedArray::cast(result)) { 7368 if (elms != FixedArray::cast(result)) {
7234 set_elements(FixedArray::cast(result)); 7369 set_elements(FixedArray::cast(result));
7235 } 7370 }
7236 } 7371 }
7237 7372
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
7270 7405
7271 return value; 7406 return value;
7272 } 7407 }
7273 default: 7408 default:
7274 UNREACHABLE(); 7409 UNREACHABLE();
7275 break; 7410 break;
7276 } 7411 }
7277 // All possible cases have been handled above. Add a return to avoid the 7412 // All possible cases have been handled above. Add a return to avoid the
7278 // complaints from the compiler. 7413 // complaints from the compiler.
7279 UNREACHABLE(); 7414 UNREACHABLE();
7280 return Heap::null_value(); 7415 return isolate->heap()->null_value();
7281 } 7416 }
7282 7417
7283 7418
7284 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, 7419 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index,
7285 Object* value) { 7420 Object* value) {
7286 uint32_t old_len = 0; 7421 uint32_t old_len = 0;
7287 CHECK(length()->ToArrayIndex(&old_len)); 7422 CHECK(length()->ToArrayIndex(&old_len));
7288 // Check to see if we need to update the length. For now, we make 7423 // Check to see if we need to update the length. For now, we make
7289 // sure that the length stays within 32-bits (unsigned). 7424 // sure that the length stays within 32-bits (unsigned).
7290 if (index >= old_len && index != 0xffffffff) { 7425 if (index >= old_len && index != 0xffffffff) {
7291 Object* len; 7426 Object* len;
7292 { MaybeObject* maybe_len = 7427 { MaybeObject* maybe_len =
7293 Heap::NumberFromDouble(static_cast<double>(index) + 1); 7428 GetHeap()->NumberFromDouble(static_cast<double>(index) + 1);
7294 if (!maybe_len->ToObject(&len)) return maybe_len; 7429 if (!maybe_len->ToObject(&len)) return maybe_len;
7295 } 7430 }
7296 set_length(len); 7431 set_length(len);
7297 } 7432 }
7298 return value; 7433 return value;
7299 } 7434 }
7300 7435
7301 7436
7302 MaybeObject* JSObject::GetElementPostInterceptor(Object* receiver, 7437 MaybeObject* JSObject::GetElementPostInterceptor(Object* receiver,
7303 uint32_t index) { 7438 uint32_t index) {
7439 Heap* heap = GetHeap();
7304 // Get element works for both JSObject and JSArray since 7440 // Get element works for both JSObject and JSArray since
7305 // JSArray::length cannot change. 7441 // JSArray::length cannot change.
7306 switch (GetElementsKind()) { 7442 switch (GetElementsKind()) {
7307 case FAST_ELEMENTS: { 7443 case FAST_ELEMENTS: {
7308 FixedArray* elms = FixedArray::cast(elements()); 7444 FixedArray* elms = FixedArray::cast(elements());
7309 if (index < static_cast<uint32_t>(elms->length())) { 7445 if (index < static_cast<uint32_t>(elms->length())) {
7310 Object* value = elms->get(index); 7446 Object* value = elms->get(index);
7311 if (!value->IsTheHole()) return value; 7447 if (!value->IsTheHole()) return value;
7312 } 7448 }
7313 break; 7449 break;
(...skipping 28 matching lines...) Expand all
7342 } 7478 }
7343 break; 7479 break;
7344 } 7480 }
7345 default: 7481 default:
7346 UNREACHABLE(); 7482 UNREACHABLE();
7347 break; 7483 break;
7348 } 7484 }
7349 7485
7350 // Continue searching via the prototype chain. 7486 // Continue searching via the prototype chain.
7351 Object* pt = GetPrototype(); 7487 Object* pt = GetPrototype();
7352 if (pt == Heap::null_value()) return Heap::undefined_value(); 7488 if (pt->IsNull()) return heap->undefined_value();
7353 return pt->GetElementWithReceiver(receiver, index); 7489 return pt->GetElementWithReceiver(receiver, index);
7354 } 7490 }
7355 7491
7356 7492
7357 MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver, 7493 MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver,
7358 uint32_t index) { 7494 uint32_t index) {
7495 Isolate* isolate = GetIsolate();
7359 // Make sure that the top context does not change when doing 7496 // Make sure that the top context does not change when doing
7360 // callbacks or interceptor calls. 7497 // callbacks or interceptor calls.
7361 AssertNoContextChange ncc; 7498 AssertNoContextChange ncc;
7362 HandleScope scope; 7499 HandleScope scope(isolate);
7363 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); 7500 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
7364 Handle<Object> this_handle(receiver); 7501 Handle<Object> this_handle(receiver);
7365 Handle<JSObject> holder_handle(this); 7502 Handle<JSObject> holder_handle(this);
7366 7503
7367 if (!interceptor->getter()->IsUndefined()) { 7504 if (!interceptor->getter()->IsUndefined()) {
7368 v8::IndexedPropertyGetter getter = 7505 v8::IndexedPropertyGetter getter =
7369 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter()); 7506 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter());
7370 LOG(ApiIndexedPropertyAccess("interceptor-indexed-get", this, index)); 7507 LOG(isolate,
7371 CustomArguments args(interceptor->data(), receiver, this); 7508 ApiIndexedPropertyAccess("interceptor-indexed-get", this, index));
7509 CustomArguments args(isolate, interceptor->data(), receiver, this);
7372 v8::AccessorInfo info(args.end()); 7510 v8::AccessorInfo info(args.end());
7373 v8::Handle<v8::Value> result; 7511 v8::Handle<v8::Value> result;
7374 { 7512 {
7375 // Leaving JavaScript. 7513 // Leaving JavaScript.
7376 VMState state(EXTERNAL); 7514 VMState state(isolate, EXTERNAL);
7377 result = getter(index, info); 7515 result = getter(index, info);
7378 } 7516 }
7379 RETURN_IF_SCHEDULED_EXCEPTION(); 7517 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
7380 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); 7518 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
7381 } 7519 }
7382 7520
7383 MaybeObject* raw_result = 7521 MaybeObject* raw_result =
7384 holder_handle->GetElementPostInterceptor(*this_handle, index); 7522 holder_handle->GetElementPostInterceptor(*this_handle, index);
7385 RETURN_IF_SCHEDULED_EXCEPTION(); 7523 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
7386 return raw_result; 7524 return raw_result;
7387 } 7525 }
7388 7526
7389 7527
7390 MaybeObject* JSObject::GetElementWithReceiver(Object* receiver, 7528 MaybeObject* JSObject::GetElementWithReceiver(Object* receiver,
7391 uint32_t index) { 7529 uint32_t index) {
7530 Heap* heap = GetHeap();
7392 // Check access rights if needed. 7531 // Check access rights if needed.
7393 if (IsAccessCheckNeeded() && 7532 if (IsAccessCheckNeeded() &&
7394 !Top::MayIndexedAccess(this, index, v8::ACCESS_GET)) { 7533 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_GET)) {
7395 Top::ReportFailedAccessCheck(this, v8::ACCESS_GET); 7534 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET);
7396 return Heap::undefined_value(); 7535 return heap->undefined_value();
7397 } 7536 }
7398 7537
7399 if (HasIndexedInterceptor()) { 7538 if (HasIndexedInterceptor()) {
7400 return GetElementWithInterceptor(receiver, index); 7539 return GetElementWithInterceptor(receiver, index);
7401 } 7540 }
7402 7541
7403 // Get element works for both JSObject and JSArray since 7542 // Get element works for both JSObject and JSArray since
7404 // JSArray::length cannot change. 7543 // JSArray::length cannot change.
7405 switch (GetElementsKind()) { 7544 switch (GetElementsKind()) {
7406 case FAST_ELEMENTS: { 7545 case FAST_ELEMENTS: {
(...skipping 30 matching lines...) Expand all
7437 index, 7576 index,
7438 this); 7577 this);
7439 } 7578 }
7440 return element; 7579 return element;
7441 } 7580 }
7442 break; 7581 break;
7443 } 7582 }
7444 } 7583 }
7445 7584
7446 Object* pt = GetPrototype(); 7585 Object* pt = GetPrototype();
7447 if (pt == Heap::null_value()) return Heap::undefined_value(); 7586 if (pt == heap->null_value()) return heap->undefined_value();
7448 return pt->GetElementWithReceiver(receiver, index); 7587 return pt->GetElementWithReceiver(receiver, index);
7449 } 7588 }
7450 7589
7451 7590
7452 MaybeObject* JSObject::GetExternalElement(uint32_t index) { 7591 MaybeObject* JSObject::GetExternalElement(uint32_t index) {
7453 // Get element works for both JSObject and JSArray since 7592 // Get element works for both JSObject and JSArray since
7454 // JSArray::length cannot change. 7593 // JSArray::length cannot change.
7455 switch (GetElementsKind()) { 7594 switch (GetElementsKind()) {
7456 case EXTERNAL_PIXEL_ELEMENTS: { 7595 case EXTERNAL_PIXEL_ELEMENTS: {
7457 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); 7596 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
7492 if (index < static_cast<uint32_t>(array->length())) { 7631 if (index < static_cast<uint32_t>(array->length())) {
7493 uint16_t value = array->get(index); 7632 uint16_t value = array->get(index);
7494 return Smi::FromInt(value); 7633 return Smi::FromInt(value);
7495 } 7634 }
7496 break; 7635 break;
7497 } 7636 }
7498 case EXTERNAL_INT_ELEMENTS: { 7637 case EXTERNAL_INT_ELEMENTS: {
7499 ExternalIntArray* array = ExternalIntArray::cast(elements()); 7638 ExternalIntArray* array = ExternalIntArray::cast(elements());
7500 if (index < static_cast<uint32_t>(array->length())) { 7639 if (index < static_cast<uint32_t>(array->length())) {
7501 int32_t value = array->get(index); 7640 int32_t value = array->get(index);
7502 return Heap::NumberFromInt32(value); 7641 return GetHeap()->NumberFromInt32(value);
7503 } 7642 }
7504 break; 7643 break;
7505 } 7644 }
7506 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { 7645 case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
7507 ExternalUnsignedIntArray* array = 7646 ExternalUnsignedIntArray* array =
7508 ExternalUnsignedIntArray::cast(elements()); 7647 ExternalUnsignedIntArray::cast(elements());
7509 if (index < static_cast<uint32_t>(array->length())) { 7648 if (index < static_cast<uint32_t>(array->length())) {
7510 uint32_t value = array->get(index); 7649 uint32_t value = array->get(index);
7511 return Heap::NumberFromUint32(value); 7650 return GetHeap()->NumberFromUint32(value);
7512 } 7651 }
7513 break; 7652 break;
7514 } 7653 }
7515 case EXTERNAL_FLOAT_ELEMENTS: { 7654 case EXTERNAL_FLOAT_ELEMENTS: {
7516 ExternalFloatArray* array = ExternalFloatArray::cast(elements()); 7655 ExternalFloatArray* array = ExternalFloatArray::cast(elements());
7517 if (index < static_cast<uint32_t>(array->length())) { 7656 if (index < static_cast<uint32_t>(array->length())) {
7518 float value = array->get(index); 7657 float value = array->get(index);
7519 return Heap::AllocateHeapNumber(value); 7658 return GetHeap()->AllocateHeapNumber(value);
7520 } 7659 }
7521 break; 7660 break;
7522 } 7661 }
7523 case FAST_ELEMENTS: 7662 case FAST_ELEMENTS:
7524 case DICTIONARY_ELEMENTS: 7663 case DICTIONARY_ELEMENTS:
7525 UNREACHABLE(); 7664 UNREACHABLE();
7526 break; 7665 break;
7527 } 7666 }
7528 return Heap::undefined_value(); 7667 return GetHeap()->undefined_value();
7529 } 7668 }
7530 7669
7531 7670
7532 bool JSObject::HasDenseElements() { 7671 bool JSObject::HasDenseElements() {
7533 int capacity = 0; 7672 int capacity = 0;
7534 int number_of_elements = 0; 7673 int number_of_elements = 0;
7535 7674
7536 switch (GetElementsKind()) { 7675 switch (GetElementsKind()) {
7537 case FAST_ELEMENTS: { 7676 case FAST_ELEMENTS: {
7538 FixedArray* elms = FixedArray::cast(elements()); 7677 FixedArray* elms = FixedArray::cast(elements());
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
7663 Object* result = 7802 Object* result =
7664 constructor->shared()->get_api_func_data()->indexed_property_handler(); 7803 constructor->shared()->get_api_func_data()->indexed_property_handler();
7665 return InterceptorInfo::cast(result); 7804 return InterceptorInfo::cast(result);
7666 } 7805 }
7667 7806
7668 7807
7669 MaybeObject* JSObject::GetPropertyPostInterceptor( 7808 MaybeObject* JSObject::GetPropertyPostInterceptor(
7670 JSObject* receiver, 7809 JSObject* receiver,
7671 String* name, 7810 String* name,
7672 PropertyAttributes* attributes) { 7811 PropertyAttributes* attributes) {
7812 Heap* heap = GetHeap();
7673 // Check local property in holder, ignore interceptor. 7813 // Check local property in holder, ignore interceptor.
7674 LookupResult result; 7814 LookupResult result;
7675 LocalLookupRealNamedProperty(name, &result); 7815 LocalLookupRealNamedProperty(name, &result);
7676 if (result.IsProperty()) { 7816 if (result.IsProperty()) {
7677 return GetProperty(receiver, &result, name, attributes); 7817 return GetProperty(receiver, &result, name, attributes);
7678 } 7818 }
7679 // Continue searching via the prototype chain. 7819 // Continue searching via the prototype chain.
7680 Object* pt = GetPrototype(); 7820 Object* pt = GetPrototype();
7681 *attributes = ABSENT; 7821 *attributes = ABSENT;
7682 if (pt == Heap::null_value()) return Heap::undefined_value(); 7822 if (pt->IsNull()) return heap->undefined_value();
7683 return pt->GetPropertyWithReceiver(receiver, name, attributes); 7823 return pt->GetPropertyWithReceiver(receiver, name, attributes);
7684 } 7824 }
7685 7825
7686 7826
7687 MaybeObject* JSObject::GetLocalPropertyPostInterceptor( 7827 MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
7688 JSObject* receiver, 7828 JSObject* receiver,
7689 String* name, 7829 String* name,
7690 PropertyAttributes* attributes) { 7830 PropertyAttributes* attributes) {
7831 Heap* heap = GetHeap();
7691 // Check local property in holder, ignore interceptor. 7832 // Check local property in holder, ignore interceptor.
7692 LookupResult result; 7833 LookupResult result;
7693 LocalLookupRealNamedProperty(name, &result); 7834 LocalLookupRealNamedProperty(name, &result);
7694 if (result.IsProperty()) { 7835 if (result.IsProperty()) {
7695 return GetProperty(receiver, &result, name, attributes); 7836 return GetProperty(receiver, &result, name, attributes);
7696 } 7837 }
7697 return Heap::undefined_value(); 7838 return heap->undefined_value();
7698 } 7839 }
7699 7840
7700 7841
7701 MaybeObject* JSObject::GetPropertyWithInterceptor( 7842 MaybeObject* JSObject::GetPropertyWithInterceptor(
7702 JSObject* receiver, 7843 JSObject* receiver,
7703 String* name, 7844 String* name,
7704 PropertyAttributes* attributes) { 7845 PropertyAttributes* attributes) {
7846 Isolate* isolate = GetIsolate();
7705 InterceptorInfo* interceptor = GetNamedInterceptor(); 7847 InterceptorInfo* interceptor = GetNamedInterceptor();
7706 HandleScope scope; 7848 HandleScope scope(isolate);
7707 Handle<JSObject> receiver_handle(receiver); 7849 Handle<JSObject> receiver_handle(receiver);
7708 Handle<JSObject> holder_handle(this); 7850 Handle<JSObject> holder_handle(this);
7709 Handle<String> name_handle(name); 7851 Handle<String> name_handle(name);
7710 7852
7711 if (!interceptor->getter()->IsUndefined()) { 7853 if (!interceptor->getter()->IsUndefined()) {
7712 v8::NamedPropertyGetter getter = 7854 v8::NamedPropertyGetter getter =
7713 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter()); 7855 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter());
7714 LOG(ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name)); 7856 LOG(isolate,
7715 CustomArguments args(interceptor->data(), receiver, this); 7857 ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name));
7858 CustomArguments args(isolate, interceptor->data(), receiver, this);
7716 v8::AccessorInfo info(args.end()); 7859 v8::AccessorInfo info(args.end());
7717 v8::Handle<v8::Value> result; 7860 v8::Handle<v8::Value> result;
7718 { 7861 {
7719 // Leaving JavaScript. 7862 // Leaving JavaScript.
7720 VMState state(EXTERNAL); 7863 VMState state(isolate, EXTERNAL);
7721 result = getter(v8::Utils::ToLocal(name_handle), info); 7864 result = getter(v8::Utils::ToLocal(name_handle), info);
7722 } 7865 }
7723 RETURN_IF_SCHEDULED_EXCEPTION(); 7866 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
7724 if (!result.IsEmpty()) { 7867 if (!result.IsEmpty()) {
7725 *attributes = NONE; 7868 *attributes = NONE;
7726 return *v8::Utils::OpenHandle(*result); 7869 return *v8::Utils::OpenHandle(*result);
7727 } 7870 }
7728 } 7871 }
7729 7872
7730 MaybeObject* result = holder_handle->GetPropertyPostInterceptor( 7873 MaybeObject* result = holder_handle->GetPropertyPostInterceptor(
7731 *receiver_handle, 7874 *receiver_handle,
7732 *name_handle, 7875 *name_handle,
7733 attributes); 7876 attributes);
7734 RETURN_IF_SCHEDULED_EXCEPTION(); 7877 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
7735 return result; 7878 return result;
7736 } 7879 }
7737 7880
7738 7881
7739 bool JSObject::HasRealNamedProperty(String* key) { 7882 bool JSObject::HasRealNamedProperty(String* key) {
7883 Heap* heap = GetHeap();
7740 // Check access rights if needed. 7884 // Check access rights if needed.
7741 if (IsAccessCheckNeeded() && 7885 if (IsAccessCheckNeeded() &&
7742 !Top::MayNamedAccess(this, key, v8::ACCESS_HAS)) { 7886 !heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) {
7743 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); 7887 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
7744 return false; 7888 return false;
7745 } 7889 }
7746 7890
7747 LookupResult result; 7891 LookupResult result;
7748 LocalLookupRealNamedProperty(key, &result); 7892 LocalLookupRealNamedProperty(key, &result);
7749 return result.IsProperty() && (result.type() != INTERCEPTOR); 7893 return result.IsProperty() && (result.type() != INTERCEPTOR);
7750 } 7894 }
7751 7895
7752 7896
7753 bool JSObject::HasRealElementProperty(uint32_t index) { 7897 bool JSObject::HasRealElementProperty(uint32_t index) {
7898 Heap* heap = GetHeap();
7754 // Check access rights if needed. 7899 // Check access rights if needed.
7755 if (IsAccessCheckNeeded() && 7900 if (IsAccessCheckNeeded() &&
7756 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) { 7901 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) {
7757 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); 7902 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
7758 return false; 7903 return false;
7759 } 7904 }
7760 7905
7761 // Handle [] on String objects. 7906 // Handle [] on String objects.
7762 if (this->IsStringObjectWithCharacterAt(index)) return true; 7907 if (this->IsStringObjectWithCharacterAt(index)) return true;
7763 7908
7764 switch (GetElementsKind()) { 7909 switch (GetElementsKind()) {
7765 case FAST_ELEMENTS: { 7910 case FAST_ELEMENTS: {
7766 uint32_t length = IsJSArray() ? 7911 uint32_t length = IsJSArray() ?
7767 static_cast<uint32_t>( 7912 static_cast<uint32_t>(
(...skipping 19 matching lines...) Expand all
7787 case DICTIONARY_ELEMENTS: { 7932 case DICTIONARY_ELEMENTS: {
7788 return element_dictionary()->FindEntry(index) 7933 return element_dictionary()->FindEntry(index)
7789 != NumberDictionary::kNotFound; 7934 != NumberDictionary::kNotFound;
7790 } 7935 }
7791 default: 7936 default:
7792 UNREACHABLE(); 7937 UNREACHABLE();
7793 break; 7938 break;
7794 } 7939 }
7795 // All possibilities have been handled above already. 7940 // All possibilities have been handled above already.
7796 UNREACHABLE(); 7941 UNREACHABLE();
7797 return Heap::null_value(); 7942 return heap->null_value();
7798 } 7943 }
7799 7944
7800 7945
7801 bool JSObject::HasRealNamedCallbackProperty(String* key) { 7946 bool JSObject::HasRealNamedCallbackProperty(String* key) {
7947 Heap* heap = GetHeap();
7802 // Check access rights if needed. 7948 // Check access rights if needed.
7803 if (IsAccessCheckNeeded() && 7949 if (IsAccessCheckNeeded() &&
7804 !Top::MayNamedAccess(this, key, v8::ACCESS_HAS)) { 7950 !heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) {
7805 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); 7951 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
7806 return false; 7952 return false;
7807 } 7953 }
7808 7954
7809 LookupResult result; 7955 LookupResult result;
7810 LocalLookupRealNamedProperty(key, &result); 7956 LocalLookupRealNamedProperty(key, &result);
7811 return result.IsProperty() && (result.type() == CALLBACKS); 7957 return result.IsProperty() && (result.type() == CALLBACKS);
7812 } 7958 }
7813 7959
7814 7960
7815 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { 7961 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) {
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
8058 return counter; 8204 return counter;
8059 } 8205 }
8060 8206
8061 8207
8062 int JSObject::GetEnumElementKeys(FixedArray* storage) { 8208 int JSObject::GetEnumElementKeys(FixedArray* storage) {
8063 return GetLocalElementKeys(storage, 8209 return GetLocalElementKeys(storage,
8064 static_cast<PropertyAttributes>(DONT_ENUM)); 8210 static_cast<PropertyAttributes>(DONT_ENUM));
8065 } 8211 }
8066 8212
8067 8213
8068 bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
8069 ASSERT(other->IsNumber());
8070 return key == static_cast<uint32_t>(other->Number());
8071 }
8072
8073
8074 uint32_t NumberDictionaryShape::Hash(uint32_t key) {
8075 return ComputeIntegerHash(key);
8076 }
8077
8078
8079 uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
8080 ASSERT(other->IsNumber());
8081 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
8082 }
8083
8084
8085 MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
8086 return Heap::NumberFromUint32(key);
8087 }
8088
8089
8090 bool StringDictionaryShape::IsMatch(String* key, Object* other) {
8091 // We know that all entries in a hash table had their hash keys created.
8092 // Use that knowledge to have fast failure.
8093 if (key->Hash() != String::cast(other)->Hash()) return false;
8094 return key->Equals(String::cast(other));
8095 }
8096
8097
8098 uint32_t StringDictionaryShape::Hash(String* key) {
8099 return key->Hash();
8100 }
8101
8102
8103 uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
8104 return String::cast(other)->Hash();
8105 }
8106
8107
8108 MaybeObject* StringDictionaryShape::AsObject(String* key) {
8109 return key;
8110 }
8111
8112
8113 // StringKey simply carries a string object as key. 8214 // StringKey simply carries a string object as key.
8114 class StringKey : public HashTableKey { 8215 class StringKey : public HashTableKey {
8115 public: 8216 public:
8116 explicit StringKey(String* string) : 8217 explicit StringKey(String* string) :
8117 string_(string), 8218 string_(string),
8118 hash_(HashForObject(string)) { } 8219 hash_(HashForObject(string)) { }
8119 8220
8120 bool IsMatch(Object* string) { 8221 bool IsMatch(Object* string) {
8121 // We know that all entries in a hash table had their hash keys created. 8222 // We know that all entries in a hash table had their hash keys created.
8122 // Use that knowledge to have fast failure. 8223 // Use that knowledge to have fast failure.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
8185 FixedArray* pair = FixedArray::cast(obj); 8286 FixedArray* pair = FixedArray::cast(obj);
8186 SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0)); 8287 SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0));
8187 String* source = String::cast(pair->get(1)); 8288 String* source = String::cast(pair->get(1));
8188 StrictModeFlag strict_mode = static_cast<StrictModeFlag>( 8289 StrictModeFlag strict_mode = static_cast<StrictModeFlag>(
8189 Smi::cast(pair->get(2))->value()); 8290 Smi::cast(pair->get(2))->value());
8190 return StringSharedHashHelper(source, shared, strict_mode); 8291 return StringSharedHashHelper(source, shared, strict_mode);
8191 } 8292 }
8192 8293
8193 MUST_USE_RESULT MaybeObject* AsObject() { 8294 MUST_USE_RESULT MaybeObject* AsObject() {
8194 Object* obj; 8295 Object* obj;
8195 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(3); 8296 { MaybeObject* maybe_obj = source_->GetHeap()->AllocateFixedArray(3);
8196 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 8297 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8197 } 8298 }
8198 FixedArray* pair = FixedArray::cast(obj); 8299 FixedArray* pair = FixedArray::cast(obj);
8199 pair->set(0, shared_); 8300 pair->set(0, shared_);
8200 pair->set(1, source_); 8301 pair->set(1, source_);
8201 pair->set(2, Smi::FromInt(strict_mode_)); 8302 pair->set(2, Smi::FromInt(strict_mode_));
8202 return pair; 8303 return pair;
8203 } 8304 }
8204 8305
8205 private: 8306 private:
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
8269 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. 8370 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed.
8270 return result; 8371 return result;
8271 } 8372 }
8272 8373
8273 uint32_t HashForObject(Object* other) { 8374 uint32_t HashForObject(Object* other) {
8274 return String::cast(other)->Hash(); 8375 return String::cast(other)->Hash();
8275 } 8376 }
8276 8377
8277 MaybeObject* AsObject() { 8378 MaybeObject* AsObject() {
8278 if (hash_field_ == 0) Hash(); 8379 if (hash_field_ == 0) Hash();
8279 return Heap::AllocateSymbol(string_, chars_, hash_field_); 8380 return Isolate::Current()->heap()->AllocateSymbol(
8381 string_, chars_, hash_field_);
8280 } 8382 }
8281 8383
8282 Vector<const char> string_; 8384 Vector<const char> string_;
8283 uint32_t hash_field_; 8385 uint32_t hash_field_;
8284 int chars_; // Caches the number of characters when computing the hash code. 8386 int chars_; // Caches the number of characters when computing the hash code.
8285 }; 8387 };
8286 8388
8287 8389
8288 template <typename Char> 8390 template <typename Char>
8289 class SequentialSymbolKey : public HashTableKey { 8391 class SequentialSymbolKey : public HashTableKey {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
8336 public: 8438 public:
8337 explicit AsciiSymbolKey(Vector<const char> str) 8439 explicit AsciiSymbolKey(Vector<const char> str)
8338 : SequentialSymbolKey<char>(str) { } 8440 : SequentialSymbolKey<char>(str) { }
8339 8441
8340 bool IsMatch(Object* string) { 8442 bool IsMatch(Object* string) {
8341 return String::cast(string)->IsAsciiEqualTo(string_); 8443 return String::cast(string)->IsAsciiEqualTo(string_);
8342 } 8444 }
8343 8445
8344 MaybeObject* AsObject() { 8446 MaybeObject* AsObject() {
8345 if (hash_field_ == 0) Hash(); 8447 if (hash_field_ == 0) Hash();
8346 return Heap::AllocateAsciiSymbol(string_, hash_field_); 8448 return HEAP->AllocateAsciiSymbol(string_, hash_field_);
8347 } 8449 }
8348 }; 8450 };
8349 8451
8350 8452
8351 class TwoByteSymbolKey : public SequentialSymbolKey<uc16> { 8453 class TwoByteSymbolKey : public SequentialSymbolKey<uc16> {
8352 public: 8454 public:
8353 explicit TwoByteSymbolKey(Vector<const uc16> str) 8455 explicit TwoByteSymbolKey(Vector<const uc16> str)
8354 : SequentialSymbolKey<uc16>(str) { } 8456 : SequentialSymbolKey<uc16>(str) { }
8355 8457
8356 bool IsMatch(Object* string) { 8458 bool IsMatch(Object* string) {
8357 return String::cast(string)->IsTwoByteEqualTo(string_); 8459 return String::cast(string)->IsTwoByteEqualTo(string_);
8358 } 8460 }
8359 8461
8360 MaybeObject* AsObject() { 8462 MaybeObject* AsObject() {
8361 if (hash_field_ == 0) Hash(); 8463 if (hash_field_ == 0) Hash();
8362 return Heap::AllocateTwoByteSymbol(string_, hash_field_); 8464 return HEAP->AllocateTwoByteSymbol(string_, hash_field_);
8363 } 8465 }
8364 }; 8466 };
8365 8467
8366 8468
8367 // SymbolKey carries a string/symbol object as key. 8469 // SymbolKey carries a string/symbol object as key.
8368 class SymbolKey : public HashTableKey { 8470 class SymbolKey : public HashTableKey {
8369 public: 8471 public:
8370 explicit SymbolKey(String* string) : string_(string) { } 8472 explicit SymbolKey(String* string)
8473 : string_(string) { }
8371 8474
8372 bool IsMatch(Object* string) { 8475 bool IsMatch(Object* string) {
8373 return String::cast(string)->Equals(string_); 8476 return String::cast(string)->Equals(string_);
8374 } 8477 }
8375 8478
8376 uint32_t Hash() { return string_->Hash(); } 8479 uint32_t Hash() { return string_->Hash(); }
8377 8480
8378 uint32_t HashForObject(Object* other) { 8481 uint32_t HashForObject(Object* other) {
8379 return String::cast(other)->Hash(); 8482 return String::cast(other)->Hash();
8380 } 8483 }
8381 8484
8382 MaybeObject* AsObject() { 8485 MaybeObject* AsObject() {
8383 // Attempt to flatten the string, so that symbols will most often 8486 // Attempt to flatten the string, so that symbols will most often
8384 // be flat strings. 8487 // be flat strings.
8385 string_ = string_->TryFlattenGetString(); 8488 string_ = string_->TryFlattenGetString();
8489 Heap* heap = string_->GetHeap();
8386 // Transform string to symbol if possible. 8490 // Transform string to symbol if possible.
8387 Map* map = Heap::SymbolMapForString(string_); 8491 Map* map = heap->SymbolMapForString(string_);
8388 if (map != NULL) { 8492 if (map != NULL) {
8389 string_->set_map(map); 8493 string_->set_map(map);
8390 ASSERT(string_->IsSymbol()); 8494 ASSERT(string_->IsSymbol());
8391 return string_; 8495 return string_;
8392 } 8496 }
8393 // Otherwise allocate a new symbol. 8497 // Otherwise allocate a new symbol.
8394 StringInputBuffer buffer(string_); 8498 StringInputBuffer buffer(string_);
8395 return Heap::AllocateInternalSymbol(&buffer, 8499 return heap->AllocateInternalSymbol(&buffer,
8396 string_->length(), 8500 string_->length(),
8397 string_->hash_field()); 8501 string_->hash_field());
8398 } 8502 }
8399 8503
8400 static uint32_t StringHash(Object* obj) { 8504 static uint32_t StringHash(Object* obj) {
8401 return String::cast(obj)->Hash(); 8505 return String::cast(obj)->Hash();
8402 } 8506 }
8403 8507
8404 String* string_; 8508 String* string_;
8405 }; 8509 };
(...skipping 18 matching lines...) Expand all
8424 PretenureFlag pretenure) { 8528 PretenureFlag pretenure) {
8425 const int kMinCapacity = 32; 8529 const int kMinCapacity = 32;
8426 int capacity = RoundUpToPowerOf2(at_least_space_for * 2); 8530 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
8427 if (capacity < kMinCapacity) { 8531 if (capacity < kMinCapacity) {
8428 capacity = kMinCapacity; // Guarantee min capacity. 8532 capacity = kMinCapacity; // Guarantee min capacity.
8429 } else if (capacity > HashTable::kMaxCapacity) { 8533 } else if (capacity > HashTable::kMaxCapacity) {
8430 return Failure::OutOfMemoryException(); 8534 return Failure::OutOfMemoryException();
8431 } 8535 }
8432 8536
8433 Object* obj; 8537 Object* obj;
8434 { MaybeObject* maybe_obj = 8538 { MaybeObject* maybe_obj = Isolate::Current()->heap()->
8435 Heap::AllocateHashTable(EntryToIndex(capacity), pretenure); 8539 AllocateHashTable(EntryToIndex(capacity), pretenure);
8436 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 8540 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8437 } 8541 }
8438 HashTable::cast(obj)->SetNumberOfElements(0); 8542 HashTable::cast(obj)->SetNumberOfElements(0);
8439 HashTable::cast(obj)->SetNumberOfDeletedElements(0); 8543 HashTable::cast(obj)->SetNumberOfDeletedElements(0);
8440 HashTable::cast(obj)->SetCapacity(capacity); 8544 HashTable::cast(obj)->SetCapacity(capacity);
8441 return obj; 8545 return obj;
8442 } 8546 }
8443 8547
8444 8548
8445 // Find entry for key otherwise return kNotFound. 8549 // Find entry for key otherwise return kNotFound.
8446 template<typename Shape, typename Key>
8447 int HashTable<Shape, Key>::FindEntry(Key key) {
8448 uint32_t capacity = Capacity();
8449 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
8450 uint32_t count = 1;
8451 // EnsureCapacity will guarantee the hash table is never full.
8452 while (true) {
8453 Object* element = KeyAt(entry);
8454 if (element->IsUndefined()) break; // Empty entry.
8455 if (!element->IsNull() && Shape::IsMatch(key, element)) return entry;
8456 entry = NextProbe(entry, count++, capacity);
8457 }
8458 return kNotFound;
8459 }
8460
8461
8462 // Find entry for key otherwise return kNotFound.
8463 int StringDictionary::FindEntry(String* key) { 8550 int StringDictionary::FindEntry(String* key) {
8464 if (!key->IsSymbol()) { 8551 if (!key->IsSymbol()) {
8465 return HashTable<StringDictionaryShape, String*>::FindEntry(key); 8552 return HashTable<StringDictionaryShape, String*>::FindEntry(key);
8466 } 8553 }
8467 8554
8468 // Optimized for symbol key. Knowledge of the key type allows: 8555 // Optimized for symbol key. Knowledge of the key type allows:
8469 // 1. Move the check if the key is a symbol out of the loop. 8556 // 1. Move the check if the key is a symbol out of the loop.
8470 // 2. Avoid comparing hash codes in symbol to symbol comparision. 8557 // 2. Avoid comparing hash codes in symbol to symbol comparision.
8471 // 3. Detect a case when a dictionary key is not a symbol but the key is. 8558 // 3. Detect a case when a dictionary key is not a symbol but the key is.
8472 // In case of positive result the dictionary key may be replaced by 8559 // In case of positive result the dictionary key may be replaced by
(...skipping 21 matching lines...) Expand all
8494 } 8581 }
8495 ASSERT(element->IsNull() || !String::cast(element)->Equals(key)); 8582 ASSERT(element->IsNull() || !String::cast(element)->Equals(key));
8496 entry = NextProbe(entry, count++, capacity); 8583 entry = NextProbe(entry, count++, capacity);
8497 } 8584 }
8498 return kNotFound; 8585 return kNotFound;
8499 } 8586 }
8500 8587
8501 8588
8502 template<typename Shape, typename Key> 8589 template<typename Shape, typename Key>
8503 MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { 8590 MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) {
8591 Heap* heap = GetHeap();
8504 int capacity = Capacity(); 8592 int capacity = Capacity();
8505 int nof = NumberOfElements() + n; 8593 int nof = NumberOfElements() + n;
8506 int nod = NumberOfDeletedElements(); 8594 int nod = NumberOfDeletedElements();
8507 // Return if: 8595 // Return if:
8508 // 50% is still free after adding n elements and 8596 // 50% is still free after adding n elements and
8509 // at most 50% of the free elements are deleted elements. 8597 // at most 50% of the free elements are deleted elements.
8510 if (nod <= (capacity - nof) >> 1) { 8598 if (nod <= (capacity - nof) >> 1) {
8511 int needed_free = nof >> 1; 8599 int needed_free = nof >> 1;
8512 if (nof + needed_free <= capacity) return this; 8600 if (nof + needed_free <= capacity) return this;
8513 } 8601 }
8514 8602
8515 const int kMinCapacityForPretenure = 256; 8603 const int kMinCapacityForPretenure = 256;
8516 bool pretenure = 8604 bool pretenure =
8517 (capacity > kMinCapacityForPretenure) && !Heap::InNewSpace(this); 8605 (capacity > kMinCapacityForPretenure) && !heap->InNewSpace(this);
8518 Object* obj; 8606 Object* obj;
8519 { MaybeObject* maybe_obj = 8607 { MaybeObject* maybe_obj =
8520 Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED); 8608 Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED);
8521 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 8609 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8522 } 8610 }
8523 8611
8524 AssertNoAllocation no_gc; 8612 AssertNoAllocation no_gc;
8525 HashTable* table = HashTable::cast(obj); 8613 HashTable* table = HashTable::cast(obj);
8526 WriteBarrierMode mode = table->GetWriteBarrierMode(no_gc); 8614 WriteBarrierMode mode = table->GetWriteBarrierMode(no_gc);
8527 8615
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
8639 template 8727 template
8640 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); 8728 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements();
8641 8729
8642 template 8730 template
8643 int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t); 8731 int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t);
8644 8732
8645 8733
8646 // Collates undefined and unexisting elements below limit from position 8734 // Collates undefined and unexisting elements below limit from position
8647 // zero of the elements. The object stays in Dictionary mode. 8735 // zero of the elements. The object stays in Dictionary mode.
8648 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { 8736 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
8737 Heap* heap = GetHeap();
8649 ASSERT(HasDictionaryElements()); 8738 ASSERT(HasDictionaryElements());
8650 // Must stay in dictionary mode, either because of requires_slow_elements, 8739 // Must stay in dictionary mode, either because of requires_slow_elements,
8651 // or because we are not going to sort (and therefore compact) all of the 8740 // or because we are not going to sort (and therefore compact) all of the
8652 // elements. 8741 // elements.
8653 NumberDictionary* dict = element_dictionary(); 8742 NumberDictionary* dict = element_dictionary();
8654 HeapNumber* result_double = NULL; 8743 HeapNumber* result_double = NULL;
8655 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { 8744 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
8656 // Allocate space for result before we start mutating the object. 8745 // Allocate space for result before we start mutating the object.
8657 Object* new_double; 8746 Object* new_double;
8658 { MaybeObject* maybe_new_double = Heap::AllocateHeapNumber(0.0); 8747 { MaybeObject* maybe_new_double = heap->AllocateHeapNumber(0.0);
8659 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; 8748 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double;
8660 } 8749 }
8661 result_double = HeapNumber::cast(new_double); 8750 result_double = HeapNumber::cast(new_double);
8662 } 8751 }
8663 8752
8664 Object* obj; 8753 Object* obj;
8665 { MaybeObject* maybe_obj = 8754 { MaybeObject* maybe_obj =
8666 NumberDictionary::Allocate(dict->NumberOfElements()); 8755 NumberDictionary::Allocate(dict->NumberOfElements());
8667 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 8756 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8668 } 8757 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
8714 } 8803 }
8715 8804
8716 uint32_t result = pos; 8805 uint32_t result = pos;
8717 PropertyDetails no_details = PropertyDetails(NONE, NORMAL); 8806 PropertyDetails no_details = PropertyDetails(NONE, NORMAL);
8718 while (undefs > 0) { 8807 while (undefs > 0) {
8719 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { 8808 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
8720 // Adding an entry with the key beyond smi-range requires 8809 // Adding an entry with the key beyond smi-range requires
8721 // allocation. Bailout. 8810 // allocation. Bailout.
8722 return Smi::FromInt(-1); 8811 return Smi::FromInt(-1);
8723 } 8812 }
8724 new_dict->AddNumberEntry(pos, Heap::undefined_value(), no_details)-> 8813 new_dict->AddNumberEntry(pos, heap->undefined_value(), no_details)->
8725 ToObjectUnchecked(); 8814 ToObjectUnchecked();
8726 pos++; 8815 pos++;
8727 undefs--; 8816 undefs--;
8728 } 8817 }
8729 8818
8730 set_elements(new_dict); 8819 set_elements(new_dict);
8731 8820
8732 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { 8821 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) {
8733 return Smi::FromInt(static_cast<int>(result)); 8822 return Smi::FromInt(static_cast<int>(result));
8734 } 8823 }
8735 8824
8736 ASSERT_NE(NULL, result_double); 8825 ASSERT_NE(NULL, result_double);
8737 result_double->set_value(static_cast<double>(result)); 8826 result_double->set_value(static_cast<double>(result));
8738 return result_double; 8827 return result_double;
8739 } 8828 }
8740 8829
8741 8830
8742 // Collects all defined (non-hole) and non-undefined (array) elements at 8831 // Collects all defined (non-hole) and non-undefined (array) elements at
8743 // the start of the elements array. 8832 // the start of the elements array.
8744 // If the object is in dictionary mode, it is converted to fast elements 8833 // If the object is in dictionary mode, it is converted to fast elements
8745 // mode. 8834 // mode.
8746 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { 8835 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) {
8836 Heap* heap = GetHeap();
8747 ASSERT(!HasExternalArrayElements()); 8837 ASSERT(!HasExternalArrayElements());
8748 8838
8749 if (HasDictionaryElements()) { 8839 if (HasDictionaryElements()) {
8750 // Convert to fast elements containing only the existing properties. 8840 // Convert to fast elements containing only the existing properties.
8751 // Ordering is irrelevant, since we are going to sort anyway. 8841 // Ordering is irrelevant, since we are going to sort anyway.
8752 NumberDictionary* dict = element_dictionary(); 8842 NumberDictionary* dict = element_dictionary();
8753 if (IsJSArray() || dict->requires_slow_elements() || 8843 if (IsJSArray() || dict->requires_slow_elements() ||
8754 dict->max_number_key() >= limit) { 8844 dict->max_number_key() >= limit) {
8755 return PrepareSlowElementsForSort(limit); 8845 return PrepareSlowElementsForSort(limit);
8756 } 8846 }
8757 // Convert to fast elements. 8847 // Convert to fast elements.
8758 8848
8759 Object* obj; 8849 Object* obj;
8760 { MaybeObject* maybe_obj = map()->GetFastElementsMap(); 8850 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
8761 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 8851 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8762 } 8852 }
8763 Map* new_map = Map::cast(obj); 8853 Map* new_map = Map::cast(obj);
8764 8854
8765 PretenureFlag tenure = Heap::InNewSpace(this) ? NOT_TENURED: TENURED; 8855 PretenureFlag tenure = heap->InNewSpace(this) ? NOT_TENURED: TENURED;
8766 Object* new_array; 8856 Object* new_array;
8767 { MaybeObject* maybe_new_array = 8857 { MaybeObject* maybe_new_array =
8768 Heap::AllocateFixedArray(dict->NumberOfElements(), tenure); 8858 heap->AllocateFixedArray(dict->NumberOfElements(), tenure);
8769 if (!maybe_new_array->ToObject(&new_array)) return maybe_new_array; 8859 if (!maybe_new_array->ToObject(&new_array)) return maybe_new_array;
8770 } 8860 }
8771 FixedArray* fast_elements = FixedArray::cast(new_array); 8861 FixedArray* fast_elements = FixedArray::cast(new_array);
8772 dict->CopyValuesTo(fast_elements); 8862 dict->CopyValuesTo(fast_elements);
8773 8863
8774 set_map(new_map); 8864 set_map(new_map);
8775 set_elements(fast_elements); 8865 set_elements(fast_elements);
8776 } else { 8866 } else {
8777 Object* obj; 8867 Object* obj;
8778 { MaybeObject* maybe_obj = EnsureWritableFastElements(); 8868 { MaybeObject* maybe_obj = EnsureWritableFastElements();
(...skipping 12 matching lines...) Expand all
8791 } 8881 }
8792 if (limit == 0) { 8882 if (limit == 0) {
8793 return Smi::FromInt(0); 8883 return Smi::FromInt(0);
8794 } 8884 }
8795 8885
8796 HeapNumber* result_double = NULL; 8886 HeapNumber* result_double = NULL;
8797 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { 8887 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
8798 // Pessimistically allocate space for return value before 8888 // Pessimistically allocate space for return value before
8799 // we start mutating the array. 8889 // we start mutating the array.
8800 Object* new_double; 8890 Object* new_double;
8801 { MaybeObject* maybe_new_double = Heap::AllocateHeapNumber(0.0); 8891 { MaybeObject* maybe_new_double = heap->AllocateHeapNumber(0.0);
8802 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; 8892 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double;
8803 } 8893 }
8804 result_double = HeapNumber::cast(new_double); 8894 result_double = HeapNumber::cast(new_double);
8805 } 8895 }
8806 8896
8807 AssertNoAllocation no_alloc; 8897 AssertNoAllocation no_alloc;
8808 8898
8809 // Split elements into defined, undefined and the_hole, in that order. 8899 // Split elements into defined, undefined and the_hole, in that order.
8810 // Only count locations for undefined and the hole, and fill them afterwards. 8900 // Only count locations for undefined and the hole, and fill them afterwards.
8811 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_alloc); 8901 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_alloc);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
8885 // converted to a number type further up in the call chain. 8975 // converted to a number type further up in the call chain.
8886 ASSERT(value->IsUndefined()); 8976 ASSERT(value->IsUndefined());
8887 } 8977 }
8888 set(index, clamped_value); 8978 set(index, clamped_value);
8889 } 8979 }
8890 return Smi::FromInt(clamped_value); 8980 return Smi::FromInt(clamped_value);
8891 } 8981 }
8892 8982
8893 8983
8894 template<typename ExternalArrayClass, typename ValueType> 8984 template<typename ExternalArrayClass, typename ValueType>
8895 static MaybeObject* ExternalArrayIntSetter(ExternalArrayClass* receiver, 8985 static MaybeObject* ExternalArrayIntSetter(Heap* heap,
8986 ExternalArrayClass* receiver,
8896 uint32_t index, 8987 uint32_t index,
8897 Object* value) { 8988 Object* value) {
8898 ValueType cast_value = 0; 8989 ValueType cast_value = 0;
8899 if (index < static_cast<uint32_t>(receiver->length())) { 8990 if (index < static_cast<uint32_t>(receiver->length())) {
8900 if (value->IsSmi()) { 8991 if (value->IsSmi()) {
8901 int int_value = Smi::cast(value)->value(); 8992 int int_value = Smi::cast(value)->value();
8902 cast_value = static_cast<ValueType>(int_value); 8993 cast_value = static_cast<ValueType>(int_value);
8903 } else if (value->IsHeapNumber()) { 8994 } else if (value->IsHeapNumber()) {
8904 double double_value = HeapNumber::cast(value)->value(); 8995 double double_value = HeapNumber::cast(value)->value();
8905 cast_value = static_cast<ValueType>(DoubleToInt32(double_value)); 8996 cast_value = static_cast<ValueType>(DoubleToInt32(double_value));
8906 } else { 8997 } else {
8907 // Clamp undefined to zero (default). All other types have been 8998 // Clamp undefined to zero (default). All other types have been
8908 // converted to a number type further up in the call chain. 8999 // converted to a number type further up in the call chain.
8909 ASSERT(value->IsUndefined()); 9000 ASSERT(value->IsUndefined());
8910 } 9001 }
8911 receiver->set(index, cast_value); 9002 receiver->set(index, cast_value);
8912 } 9003 }
8913 return Heap::NumberFromInt32(cast_value); 9004 return heap->NumberFromInt32(cast_value);
8914 } 9005 }
8915 9006
8916 9007
8917 MaybeObject* ExternalByteArray::SetValue(uint32_t index, Object* value) { 9008 MaybeObject* ExternalByteArray::SetValue(uint32_t index, Object* value) {
8918 return ExternalArrayIntSetter<ExternalByteArray, int8_t> 9009 return ExternalArrayIntSetter<ExternalByteArray, int8_t>
8919 (this, index, value); 9010 (GetHeap(), this, index, value);
8920 } 9011 }
8921 9012
8922 9013
8923 MaybeObject* ExternalUnsignedByteArray::SetValue(uint32_t index, 9014 MaybeObject* ExternalUnsignedByteArray::SetValue(uint32_t index,
8924 Object* value) { 9015 Object* value) {
8925 return ExternalArrayIntSetter<ExternalUnsignedByteArray, uint8_t> 9016 return ExternalArrayIntSetter<ExternalUnsignedByteArray, uint8_t>
8926 (this, index, value); 9017 (GetHeap(), this, index, value);
8927 } 9018 }
8928 9019
8929 9020
8930 MaybeObject* ExternalShortArray::SetValue(uint32_t index, 9021 MaybeObject* ExternalShortArray::SetValue(uint32_t index,
8931 Object* value) { 9022 Object* value) {
8932 return ExternalArrayIntSetter<ExternalShortArray, int16_t> 9023 return ExternalArrayIntSetter<ExternalShortArray, int16_t>
8933 (this, index, value); 9024 (GetHeap(), this, index, value);
8934 } 9025 }
8935 9026
8936 9027
8937 MaybeObject* ExternalUnsignedShortArray::SetValue(uint32_t index, 9028 MaybeObject* ExternalUnsignedShortArray::SetValue(uint32_t index,
8938 Object* value) { 9029 Object* value) {
8939 return ExternalArrayIntSetter<ExternalUnsignedShortArray, uint16_t> 9030 return ExternalArrayIntSetter<ExternalUnsignedShortArray, uint16_t>
8940 (this, index, value); 9031 (GetHeap(), this, index, value);
8941 } 9032 }
8942 9033
8943 9034
8944 MaybeObject* ExternalIntArray::SetValue(uint32_t index, Object* value) { 9035 MaybeObject* ExternalIntArray::SetValue(uint32_t index, Object* value) {
8945 return ExternalArrayIntSetter<ExternalIntArray, int32_t> 9036 return ExternalArrayIntSetter<ExternalIntArray, int32_t>
8946 (this, index, value); 9037 (GetHeap(), this, index, value);
8947 } 9038 }
8948 9039
8949 9040
8950 MaybeObject* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) { 9041 MaybeObject* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) {
8951 uint32_t cast_value = 0; 9042 uint32_t cast_value = 0;
9043 Heap* heap = GetHeap();
8952 if (index < static_cast<uint32_t>(length())) { 9044 if (index < static_cast<uint32_t>(length())) {
8953 if (value->IsSmi()) { 9045 if (value->IsSmi()) {
8954 int int_value = Smi::cast(value)->value(); 9046 int int_value = Smi::cast(value)->value();
8955 cast_value = static_cast<uint32_t>(int_value); 9047 cast_value = static_cast<uint32_t>(int_value);
8956 } else if (value->IsHeapNumber()) { 9048 } else if (value->IsHeapNumber()) {
8957 double double_value = HeapNumber::cast(value)->value(); 9049 double double_value = HeapNumber::cast(value)->value();
8958 cast_value = static_cast<uint32_t>(DoubleToUint32(double_value)); 9050 cast_value = static_cast<uint32_t>(DoubleToUint32(double_value));
8959 } else { 9051 } else {
8960 // Clamp undefined to zero (default). All other types have been 9052 // Clamp undefined to zero (default). All other types have been
8961 // converted to a number type further up in the call chain. 9053 // converted to a number type further up in the call chain.
8962 ASSERT(value->IsUndefined()); 9054 ASSERT(value->IsUndefined());
8963 } 9055 }
8964 set(index, cast_value); 9056 set(index, cast_value);
8965 } 9057 }
8966 return Heap::NumberFromUint32(cast_value); 9058 return heap->NumberFromUint32(cast_value);
8967 } 9059 }
8968 9060
8969 9061
8970 MaybeObject* ExternalFloatArray::SetValue(uint32_t index, Object* value) { 9062 MaybeObject* ExternalFloatArray::SetValue(uint32_t index, Object* value) {
8971 float cast_value = 0; 9063 float cast_value = 0;
9064 Heap* heap = GetHeap();
8972 if (index < static_cast<uint32_t>(length())) { 9065 if (index < static_cast<uint32_t>(length())) {
8973 if (value->IsSmi()) { 9066 if (value->IsSmi()) {
8974 int int_value = Smi::cast(value)->value(); 9067 int int_value = Smi::cast(value)->value();
8975 cast_value = static_cast<float>(int_value); 9068 cast_value = static_cast<float>(int_value);
8976 } else if (value->IsHeapNumber()) { 9069 } else if (value->IsHeapNumber()) {
8977 double double_value = HeapNumber::cast(value)->value(); 9070 double double_value = HeapNumber::cast(value)->value();
8978 cast_value = static_cast<float>(double_value); 9071 cast_value = static_cast<float>(double_value);
8979 } else { 9072 } else {
8980 // Clamp undefined to zero (default). All other types have been 9073 // Clamp undefined to zero (default). All other types have been
8981 // converted to a number type further up in the call chain. 9074 // converted to a number type further up in the call chain.
8982 ASSERT(value->IsUndefined()); 9075 ASSERT(value->IsUndefined());
8983 } 9076 }
8984 set(index, cast_value); 9077 set(index, cast_value);
8985 } 9078 }
8986 return Heap::AllocateHeapNumber(cast_value); 9079 return heap->AllocateHeapNumber(cast_value);
8987 } 9080 }
8988 9081
8989 9082
8990 JSGlobalPropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { 9083 JSGlobalPropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) {
8991 ASSERT(!HasFastProperties()); 9084 ASSERT(!HasFastProperties());
8992 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); 9085 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
8993 return JSGlobalPropertyCell::cast(value); 9086 return JSGlobalPropertyCell::cast(value);
8994 } 9087 }
8995 9088
8996 9089
8997 MaybeObject* GlobalObject::EnsurePropertyCell(String* name) { 9090 MaybeObject* GlobalObject::EnsurePropertyCell(String* name) {
8998 ASSERT(!HasFastProperties()); 9091 ASSERT(!HasFastProperties());
9092 Heap* heap = GetHeap();
8999 int entry = property_dictionary()->FindEntry(name); 9093 int entry = property_dictionary()->FindEntry(name);
9000 if (entry == StringDictionary::kNotFound) { 9094 if (entry == StringDictionary::kNotFound) {
9001 Object* cell; 9095 Object* cell;
9002 { MaybeObject* maybe_cell = 9096 { MaybeObject* maybe_cell =
9003 Heap::AllocateJSGlobalPropertyCell(Heap::the_hole_value()); 9097 heap->AllocateJSGlobalPropertyCell(heap->the_hole_value());
9004 if (!maybe_cell->ToObject(&cell)) return maybe_cell; 9098 if (!maybe_cell->ToObject(&cell)) return maybe_cell;
9005 } 9099 }
9006 PropertyDetails details(NONE, NORMAL); 9100 PropertyDetails details(NONE, NORMAL);
9007 details = details.AsDeleted(); 9101 details = details.AsDeleted();
9008 Object* dictionary; 9102 Object* dictionary;
9009 { MaybeObject* maybe_dictionary = 9103 { MaybeObject* maybe_dictionary =
9010 property_dictionary()->Add(name, cell, details); 9104 property_dictionary()->Add(name, cell, details);
9011 if (!maybe_dictionary->ToObject(&dictionary)) return maybe_dictionary; 9105 if (!maybe_dictionary->ToObject(&dictionary)) return maybe_dictionary;
9012 } 9106 }
9013 set_properties(StringDictionary::cast(dictionary)); 9107 set_properties(StringDictionary::cast(dictionary));
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
9165 // Add the new symbol and return it along with the symbol table. 9259 // Add the new symbol and return it along with the symbol table.
9166 entry = table->FindInsertionEntry(key->Hash()); 9260 entry = table->FindInsertionEntry(key->Hash());
9167 table->set(EntryToIndex(entry), symbol); 9261 table->set(EntryToIndex(entry), symbol);
9168 table->ElementAdded(); 9262 table->ElementAdded();
9169 *s = symbol; 9263 *s = symbol;
9170 return table; 9264 return table;
9171 } 9265 }
9172 9266
9173 9267
9174 Object* CompilationCacheTable::Lookup(String* src) { 9268 Object* CompilationCacheTable::Lookup(String* src) {
9269 Heap* heap = GetHeap();
9175 StringKey key(src); 9270 StringKey key(src);
9176 int entry = FindEntry(&key); 9271 int entry = FindEntry(&key);
9177 if (entry == kNotFound) return Heap::undefined_value(); 9272 if (entry == kNotFound) return heap->undefined_value();
9178 return get(EntryToIndex(entry) + 1); 9273 return get(EntryToIndex(entry) + 1);
9179 } 9274 }
9180 9275
9181 9276
9182 Object* CompilationCacheTable::LookupEval(String* src, 9277 Object* CompilationCacheTable::LookupEval(String* src,
9183 Context* context, 9278 Context* context,
9184 StrictModeFlag strict_mode) { 9279 StrictModeFlag strict_mode) {
9185 StringSharedKey key(src, context->closure()->shared(), strict_mode); 9280 StringSharedKey key(src, context->closure()->shared(), strict_mode);
9186 int entry = FindEntry(&key); 9281 int entry = FindEntry(&key);
9187 if (entry == kNotFound) return Heap::undefined_value(); 9282 if (entry == kNotFound) return GetHeap()->undefined_value();
9188 return get(EntryToIndex(entry) + 1); 9283 return get(EntryToIndex(entry) + 1);
9189 } 9284 }
9190 9285
9191 9286
9192 Object* CompilationCacheTable::LookupRegExp(String* src, 9287 Object* CompilationCacheTable::LookupRegExp(String* src,
9193 JSRegExp::Flags flags) { 9288 JSRegExp::Flags flags) {
9289 Heap* heap = GetHeap();
9194 RegExpKey key(src, flags); 9290 RegExpKey key(src, flags);
9195 int entry = FindEntry(&key); 9291 int entry = FindEntry(&key);
9196 if (entry == kNotFound) return Heap::undefined_value(); 9292 if (entry == kNotFound) return heap->undefined_value();
9197 return get(EntryToIndex(entry) + 1); 9293 return get(EntryToIndex(entry) + 1);
9198 } 9294 }
9199 9295
9200 9296
9201 MaybeObject* CompilationCacheTable::Put(String* src, Object* value) { 9297 MaybeObject* CompilationCacheTable::Put(String* src, Object* value) {
9202 StringKey key(src); 9298 StringKey key(src);
9203 Object* obj; 9299 Object* obj;
9204 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); 9300 { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
9205 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 9301 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
9206 } 9302 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
9257 // We store the value in the key slot, and compare the search key 9353 // We store the value in the key slot, and compare the search key
9258 // to the stored value with a custon IsMatch function during lookups. 9354 // to the stored value with a custon IsMatch function during lookups.
9259 cache->set(EntryToIndex(entry), value); 9355 cache->set(EntryToIndex(entry), value);
9260 cache->set(EntryToIndex(entry) + 1, value); 9356 cache->set(EntryToIndex(entry) + 1, value);
9261 cache->ElementAdded(); 9357 cache->ElementAdded();
9262 return cache; 9358 return cache;
9263 } 9359 }
9264 9360
9265 9361
9266 void CompilationCacheTable::Remove(Object* value) { 9362 void CompilationCacheTable::Remove(Object* value) {
9363 Object* null_value = GetHeap()->null_value();
9267 for (int entry = 0, size = Capacity(); entry < size; entry++) { 9364 for (int entry = 0, size = Capacity(); entry < size; entry++) {
9268 int entry_index = EntryToIndex(entry); 9365 int entry_index = EntryToIndex(entry);
9269 int value_index = entry_index + 1; 9366 int value_index = entry_index + 1;
9270 if (get(value_index) == value) { 9367 if (get(value_index) == value) {
9271 fast_set(this, entry_index, Heap::null_value()); 9368 fast_set(this, entry_index, null_value);
9272 fast_set(this, value_index, Heap::null_value()); 9369 fast_set(this, value_index, null_value);
9273 ElementRemoved(); 9370 ElementRemoved();
9274 } 9371 }
9275 } 9372 }
9276 return; 9373 return;
9277 } 9374 }
9278 9375
9279 9376
9280 // SymbolsKey used for HashTable where key is array of symbols. 9377 // SymbolsKey used for HashTable where key is array of symbols.
9281 class SymbolsKey : public HashTableKey { 9378 class SymbolsKey : public HashTableKey {
9282 public: 9379 public:
(...skipping 22 matching lines...) Expand all
9305 } 9402 }
9306 9403
9307 Object* AsObject() { return symbols_; } 9404 Object* AsObject() { return symbols_; }
9308 9405
9309 private: 9406 private:
9310 FixedArray* symbols_; 9407 FixedArray* symbols_;
9311 }; 9408 };
9312 9409
9313 9410
9314 Object* MapCache::Lookup(FixedArray* array) { 9411 Object* MapCache::Lookup(FixedArray* array) {
9412 Heap* heap = GetHeap();
9315 SymbolsKey key(array); 9413 SymbolsKey key(array);
9316 int entry = FindEntry(&key); 9414 int entry = FindEntry(&key);
9317 if (entry == kNotFound) return Heap::undefined_value(); 9415 if (entry == kNotFound) return heap->undefined_value();
9318 return get(EntryToIndex(entry) + 1); 9416 return get(EntryToIndex(entry) + 1);
9319 } 9417 }
9320 9418
9321 9419
9322 MaybeObject* MapCache::Put(FixedArray* array, Map* value) { 9420 MaybeObject* MapCache::Put(FixedArray* array, Map* value) {
9323 SymbolsKey key(array); 9421 SymbolsKey key(array);
9324 Object* obj; 9422 Object* obj;
9325 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); 9423 { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
9326 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 9424 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
9327 } 9425 }
(...skipping 16 matching lines...) Expand all
9344 } 9442 }
9345 // Initialize the next enumeration index. 9443 // Initialize the next enumeration index.
9346 Dictionary<Shape, Key>::cast(obj)-> 9444 Dictionary<Shape, Key>::cast(obj)->
9347 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); 9445 SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
9348 return obj; 9446 return obj;
9349 } 9447 }
9350 9448
9351 9449
9352 template<typename Shape, typename Key> 9450 template<typename Shape, typename Key>
9353 MaybeObject* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() { 9451 MaybeObject* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() {
9452 Heap* heap = Dictionary<Shape, Key>::GetHeap();
9354 int length = HashTable<Shape, Key>::NumberOfElements(); 9453 int length = HashTable<Shape, Key>::NumberOfElements();
9355 9454
9356 // Allocate and initialize iteration order array. 9455 // Allocate and initialize iteration order array.
9357 Object* obj; 9456 Object* obj;
9358 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(length); 9457 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length);
9359 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 9458 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
9360 } 9459 }
9361 FixedArray* iteration_order = FixedArray::cast(obj); 9460 FixedArray* iteration_order = FixedArray::cast(obj);
9362 for (int i = 0; i < length; i++) { 9461 for (int i = 0; i < length; i++) {
9363 iteration_order->set(i, Smi::FromInt(i)); 9462 iteration_order->set(i, Smi::FromInt(i));
9364 } 9463 }
9365 9464
9366 // Allocate array with enumeration order. 9465 // Allocate array with enumeration order.
9367 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(length); 9466 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length);
9368 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 9467 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
9369 } 9468 }
9370 FixedArray* enumeration_order = FixedArray::cast(obj); 9469 FixedArray* enumeration_order = FixedArray::cast(obj);
9371 9470
9372 // Fill the enumeration order array with property details. 9471 // Fill the enumeration order array with property details.
9373 int capacity = HashTable<Shape, Key>::Capacity(); 9472 int capacity = HashTable<Shape, Key>::Capacity();
9374 int pos = 0; 9473 int pos = 0;
9375 for (int i = 0; i < capacity; i++) { 9474 for (int i = 0; i < capacity; i++) {
9376 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { 9475 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) {
9377 enumeration_order->set(pos++, Smi::FromInt(DetailsAt(i).index())); 9476 enumeration_order->set(pos++, Smi::FromInt(DetailsAt(i).index()));
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
9418 } 9517 }
9419 } 9518 }
9420 return HashTable<Shape, Key>::EnsureCapacity(n, key); 9519 return HashTable<Shape, Key>::EnsureCapacity(n, key);
9421 } 9520 }
9422 9521
9423 9522
9424 void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) { 9523 void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) {
9425 // Do nothing if the interval [from, to) is empty. 9524 // Do nothing if the interval [from, to) is empty.
9426 if (from >= to) return; 9525 if (from >= to) return;
9427 9526
9527 Heap* heap = GetHeap();
9428 int removed_entries = 0; 9528 int removed_entries = 0;
9429 Object* sentinel = Heap::null_value(); 9529 Object* sentinel = heap->null_value();
9430 int capacity = Capacity(); 9530 int capacity = Capacity();
9431 for (int i = 0; i < capacity; i++) { 9531 for (int i = 0; i < capacity; i++) {
9432 Object* key = KeyAt(i); 9532 Object* key = KeyAt(i);
9433 if (key->IsNumber()) { 9533 if (key->IsNumber()) {
9434 uint32_t number = static_cast<uint32_t>(key->Number()); 9534 uint32_t number = static_cast<uint32_t>(key->Number());
9435 if (from <= number && number < to) { 9535 if (from <= number && number < to) {
9436 SetEntry(i, sentinel, sentinel, Smi::FromInt(0)); 9536 SetEntry(i, sentinel, sentinel, Smi::FromInt(0));
9437 removed_entries++; 9537 removed_entries++;
9438 } 9538 }
9439 } 9539 }
9440 } 9540 }
9441 9541
9442 // Update the number of elements. 9542 // Update the number of elements.
9443 ElementsRemoved(removed_entries); 9543 ElementsRemoved(removed_entries);
9444 } 9544 }
9445 9545
9446 9546
9447 template<typename Shape, typename Key> 9547 template<typename Shape, typename Key>
9448 Object* Dictionary<Shape, Key>::DeleteProperty(int entry, 9548 Object* Dictionary<Shape, Key>::DeleteProperty(int entry,
9449 JSObject::DeleteMode mode) { 9549 JSObject::DeleteMode mode) {
9550 Heap* heap = Dictionary<Shape, Key>::GetHeap();
9450 PropertyDetails details = DetailsAt(entry); 9551 PropertyDetails details = DetailsAt(entry);
9451 // Ignore attributes if forcing a deletion. 9552 // Ignore attributes if forcing a deletion.
9452 if (details.IsDontDelete() && mode != JSObject::FORCE_DELETION) { 9553 if (details.IsDontDelete() && mode != JSObject::FORCE_DELETION) {
9453 return Heap::false_value(); 9554 return heap->false_value();
9454 } 9555 }
9455 SetEntry(entry, Heap::null_value(), Heap::null_value(), Smi::FromInt(0)); 9556 SetEntry(entry, heap->null_value(), heap->null_value(), Smi::FromInt(0));
9456 HashTable<Shape, Key>::ElementRemoved(); 9557 HashTable<Shape, Key>::ElementRemoved();
9457 return Heap::true_value(); 9558 return heap->true_value();
9458 } 9559 }
9459 9560
9460 9561
9461 template<typename Shape, typename Key> 9562 template<typename Shape, typename Key>
9462 MaybeObject* Dictionary<Shape, Key>::AtPut(Key key, Object* value) { 9563 MaybeObject* Dictionary<Shape, Key>::AtPut(Key key, Object* value) {
9463 int entry = this->FindEntry(key); 9564 int entry = this->FindEntry(key);
9464 9565
9465 // If the entry is present set the value; 9566 // If the entry is present set the value;
9466 if (entry != Dictionary<Shape, Key>::kNotFound) { 9567 if (entry != Dictionary<Shape, Key>::kNotFound) {
9467 ValueAtPut(entry, value); 9568 ValueAtPut(entry, value);
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
9660 storage->set(index++, k); 9761 storage->set(index++, k);
9661 } 9762 }
9662 } 9763 }
9663 ASSERT(storage->length() >= index); 9764 ASSERT(storage->length() >= index);
9664 } 9765 }
9665 9766
9666 9767
9667 // Backwards lookup (slow). 9768 // Backwards lookup (slow).
9668 template<typename Shape, typename Key> 9769 template<typename Shape, typename Key>
9669 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { 9770 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) {
9771 Heap* heap = Dictionary<Shape, Key>::GetHeap();
9670 int capacity = HashTable<Shape, Key>::Capacity(); 9772 int capacity = HashTable<Shape, Key>::Capacity();
9671 for (int i = 0; i < capacity; i++) { 9773 for (int i = 0; i < capacity; i++) {
9672 Object* k = HashTable<Shape, Key>::KeyAt(i); 9774 Object* k = HashTable<Shape, Key>::KeyAt(i);
9673 if (Dictionary<Shape, Key>::IsKey(k)) { 9775 if (Dictionary<Shape, Key>::IsKey(k)) {
9674 Object* e = ValueAt(i); 9776 Object* e = ValueAt(i);
9675 if (e->IsJSGlobalPropertyCell()) { 9777 if (e->IsJSGlobalPropertyCell()) {
9676 e = JSGlobalPropertyCell::cast(e)->value(); 9778 e = JSGlobalPropertyCell::cast(e)->value();
9677 } 9779 }
9678 if (e == value) return k; 9780 if (e == value) return k;
9679 } 9781 }
9680 } 9782 }
9681 return Heap::undefined_value(); 9783 return heap->undefined_value();
9682 } 9784 }
9683 9785
9684 9786
9685 MaybeObject* StringDictionary::TransformPropertiesToFastFor( 9787 MaybeObject* StringDictionary::TransformPropertiesToFastFor(
9686 JSObject* obj, int unused_property_fields) { 9788 JSObject* obj, int unused_property_fields) {
9789 Heap* heap = GetHeap();
9687 // Make sure we preserve dictionary representation if there are too many 9790 // Make sure we preserve dictionary representation if there are too many
9688 // descriptors. 9791 // descriptors.
9689 if (NumberOfElements() > DescriptorArray::kMaxNumberOfDescriptors) return obj; 9792 if (NumberOfElements() > DescriptorArray::kMaxNumberOfDescriptors) return obj;
9690 9793
9691 // Figure out if it is necessary to generate new enumeration indices. 9794 // Figure out if it is necessary to generate new enumeration indices.
9692 int max_enumeration_index = 9795 int max_enumeration_index =
9693 NextEnumerationIndex() + 9796 NextEnumerationIndex() +
9694 (DescriptorArray::kMaxNumberOfDescriptors - 9797 (DescriptorArray::kMaxNumberOfDescriptors -
9695 NumberOfElements()); 9798 NumberOfElements());
9696 if (!PropertyDetails::IsValidIndex(max_enumeration_index)) { 9799 if (!PropertyDetails::IsValidIndex(max_enumeration_index)) {
9697 Object* result; 9800 Object* result;
9698 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); 9801 { MaybeObject* maybe_result = GenerateNewEnumerationIndices();
9699 if (!maybe_result->ToObject(&result)) return maybe_result; 9802 if (!maybe_result->ToObject(&result)) return maybe_result;
9700 } 9803 }
9701 } 9804 }
9702 9805
9703 int instance_descriptor_length = 0; 9806 int instance_descriptor_length = 0;
9704 int number_of_fields = 0; 9807 int number_of_fields = 0;
9705 9808
9706 // Compute the length of the instance descriptor. 9809 // Compute the length of the instance descriptor.
9707 int capacity = Capacity(); 9810 int capacity = Capacity();
9708 for (int i = 0; i < capacity; i++) { 9811 for (int i = 0; i < capacity; i++) {
9709 Object* k = KeyAt(i); 9812 Object* k = KeyAt(i);
9710 if (IsKey(k)) { 9813 if (IsKey(k)) {
9711 Object* value = ValueAt(i); 9814 Object* value = ValueAt(i);
9712 PropertyType type = DetailsAt(i).type(); 9815 PropertyType type = DetailsAt(i).type();
9713 ASSERT(type != FIELD); 9816 ASSERT(type != FIELD);
9714 instance_descriptor_length++; 9817 instance_descriptor_length++;
9715 if (type == NORMAL && 9818 if (type == NORMAL &&
9716 (!value->IsJSFunction() || Heap::InNewSpace(value))) { 9819 (!value->IsJSFunction() || heap->InNewSpace(value))) {
9717 number_of_fields += 1; 9820 number_of_fields += 1;
9718 } 9821 }
9719 } 9822 }
9720 } 9823 }
9721 9824
9722 // Allocate the instance descriptor. 9825 // Allocate the instance descriptor.
9723 Object* descriptors_unchecked; 9826 Object* descriptors_unchecked;
9724 { MaybeObject* maybe_descriptors_unchecked = 9827 { MaybeObject* maybe_descriptors_unchecked =
9725 DescriptorArray::Allocate(instance_descriptor_length); 9828 DescriptorArray::Allocate(instance_descriptor_length);
9726 if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) { 9829 if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) {
9727 return maybe_descriptors_unchecked; 9830 return maybe_descriptors_unchecked;
9728 } 9831 }
9729 } 9832 }
9730 DescriptorArray* descriptors = DescriptorArray::cast(descriptors_unchecked); 9833 DescriptorArray* descriptors = DescriptorArray::cast(descriptors_unchecked);
9731 9834
9732 int inobject_props = obj->map()->inobject_properties(); 9835 int inobject_props = obj->map()->inobject_properties();
9733 int number_of_allocated_fields = 9836 int number_of_allocated_fields =
9734 number_of_fields + unused_property_fields - inobject_props; 9837 number_of_fields + unused_property_fields - inobject_props;
9735 if (number_of_allocated_fields < 0) { 9838 if (number_of_allocated_fields < 0) {
9736 // There is enough inobject space for all fields (including unused). 9839 // There is enough inobject space for all fields (including unused).
9737 number_of_allocated_fields = 0; 9840 number_of_allocated_fields = 0;
9738 unused_property_fields = inobject_props - number_of_fields; 9841 unused_property_fields = inobject_props - number_of_fields;
9739 } 9842 }
9740 9843
9741 // Allocate the fixed array for the fields. 9844 // Allocate the fixed array for the fields.
9742 Object* fields; 9845 Object* fields;
9743 { MaybeObject* maybe_fields = 9846 { MaybeObject* maybe_fields =
9744 Heap::AllocateFixedArray(number_of_allocated_fields); 9847 heap->AllocateFixedArray(number_of_allocated_fields);
9745 if (!maybe_fields->ToObject(&fields)) return maybe_fields; 9848 if (!maybe_fields->ToObject(&fields)) return maybe_fields;
9746 } 9849 }
9747 9850
9748 // Fill in the instance descriptor and the fields. 9851 // Fill in the instance descriptor and the fields.
9749 int next_descriptor = 0; 9852 int next_descriptor = 0;
9750 int current_offset = 0; 9853 int current_offset = 0;
9751 for (int i = 0; i < capacity; i++) { 9854 for (int i = 0; i < capacity; i++) {
9752 Object* k = KeyAt(i); 9855 Object* k = KeyAt(i);
9753 if (IsKey(k)) { 9856 if (IsKey(k)) {
9754 Object* value = ValueAt(i); 9857 Object* value = ValueAt(i);
9755 // Ensure the key is a symbol before writing into the instance descriptor. 9858 // Ensure the key is a symbol before writing into the instance descriptor.
9756 Object* key; 9859 Object* key;
9757 { MaybeObject* maybe_key = Heap::LookupSymbol(String::cast(k)); 9860 { MaybeObject* maybe_key = heap->LookupSymbol(String::cast(k));
9758 if (!maybe_key->ToObject(&key)) return maybe_key; 9861 if (!maybe_key->ToObject(&key)) return maybe_key;
9759 } 9862 }
9760 PropertyDetails details = DetailsAt(i); 9863 PropertyDetails details = DetailsAt(i);
9761 PropertyType type = details.type(); 9864 PropertyType type = details.type();
9762 9865
9763 if (value->IsJSFunction() && !Heap::InNewSpace(value)) { 9866 if (value->IsJSFunction() && !heap->InNewSpace(value)) {
9764 ConstantFunctionDescriptor d(String::cast(key), 9867 ConstantFunctionDescriptor d(String::cast(key),
9765 JSFunction::cast(value), 9868 JSFunction::cast(value),
9766 details.attributes(), 9869 details.attributes(),
9767 details.index()); 9870 details.index());
9768 descriptors->Set(next_descriptor++, &d); 9871 descriptors->Set(next_descriptor++, &d);
9769 } else if (type == NORMAL) { 9872 } else if (type == NORMAL) {
9770 if (current_offset < inobject_props) { 9873 if (current_offset < inobject_props) {
9771 obj->InObjectPropertyAtPut(current_offset, 9874 obj->InObjectPropertyAtPut(current_offset,
9772 value, 9875 value,
9773 UPDATE_WRITE_BARRIER); 9876 UPDATE_WRITE_BARRIER);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
9824 9927
9825 // If there is no break point info object or no break points in the break 9928 // If there is no break point info object or no break points in the break
9826 // point info object there is no break point at this code position. 9929 // point info object there is no break point at this code position.
9827 if (break_point_info->IsUndefined()) return false; 9930 if (break_point_info->IsUndefined()) return false;
9828 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; 9931 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0;
9829 } 9932 }
9830 9933
9831 9934
9832 // Get the break point info object for this code position. 9935 // Get the break point info object for this code position.
9833 Object* DebugInfo::GetBreakPointInfo(int code_position) { 9936 Object* DebugInfo::GetBreakPointInfo(int code_position) {
9937 Heap* heap = GetHeap();
9834 // Find the index of the break point info object for this code position. 9938 // Find the index of the break point info object for this code position.
9835 int index = GetBreakPointInfoIndex(code_position); 9939 int index = GetBreakPointInfoIndex(code_position);
9836 9940
9837 // Return the break point info object if any. 9941 // Return the break point info object if any.
9838 if (index == kNoBreakPointInfo) return Heap::undefined_value(); 9942 if (index == kNoBreakPointInfo) return heap->undefined_value();
9839 return BreakPointInfo::cast(break_points()->get(index)); 9943 return BreakPointInfo::cast(break_points()->get(index));
9840 } 9944 }
9841 9945
9842 9946
9843 // Clear a break point at the specified code position. 9947 // Clear a break point at the specified code position.
9844 void DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info, 9948 void DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info,
9845 int code_position, 9949 int code_position,
9846 Handle<Object> break_point_object) { 9950 Handle<Object> break_point_object) {
9847 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position)); 9951 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position));
9848 if (break_point_info->IsUndefined()) return; 9952 if (break_point_info->IsUndefined()) return;
9849 BreakPointInfo::ClearBreakPoint( 9953 BreakPointInfo::ClearBreakPoint(
9850 Handle<BreakPointInfo>::cast(break_point_info), 9954 Handle<BreakPointInfo>::cast(break_point_info),
9851 break_point_object); 9955 break_point_object);
9852 } 9956 }
9853 9957
9854 9958
9855 void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, 9959 void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info,
9856 int code_position, 9960 int code_position,
9857 int source_position, 9961 int source_position,
9858 int statement_position, 9962 int statement_position,
9859 Handle<Object> break_point_object) { 9963 Handle<Object> break_point_object) {
9964 Isolate* isolate = Isolate::Current();
9860 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position)); 9965 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position));
9861 if (!break_point_info->IsUndefined()) { 9966 if (!break_point_info->IsUndefined()) {
9862 BreakPointInfo::SetBreakPoint( 9967 BreakPointInfo::SetBreakPoint(
9863 Handle<BreakPointInfo>::cast(break_point_info), 9968 Handle<BreakPointInfo>::cast(break_point_info),
9864 break_point_object); 9969 break_point_object);
9865 return; 9970 return;
9866 } 9971 }
9867 9972
9868 // Adding a new break point for a code position which did not have any 9973 // Adding a new break point for a code position which did not have any
9869 // break points before. Try to find a free slot. 9974 // break points before. Try to find a free slot.
9870 int index = kNoBreakPointInfo; 9975 int index = kNoBreakPointInfo;
9871 for (int i = 0; i < debug_info->break_points()->length(); i++) { 9976 for (int i = 0; i < debug_info->break_points()->length(); i++) {
9872 if (debug_info->break_points()->get(i)->IsUndefined()) { 9977 if (debug_info->break_points()->get(i)->IsUndefined()) {
9873 index = i; 9978 index = i;
9874 break; 9979 break;
9875 } 9980 }
9876 } 9981 }
9877 if (index == kNoBreakPointInfo) { 9982 if (index == kNoBreakPointInfo) {
9878 // No free slot - extend break point info array. 9983 // No free slot - extend break point info array.
9879 Handle<FixedArray> old_break_points = 9984 Handle<FixedArray> old_break_points =
9880 Handle<FixedArray>(FixedArray::cast(debug_info->break_points())); 9985 Handle<FixedArray>(FixedArray::cast(debug_info->break_points()));
9881 Handle<FixedArray> new_break_points = 9986 Handle<FixedArray> new_break_points =
9882 Factory::NewFixedArray(old_break_points->length() + 9987 isolate->factory()->NewFixedArray(
9883 Debug::kEstimatedNofBreakPointsInFunction); 9988 old_break_points->length() +
9989 Debug::kEstimatedNofBreakPointsInFunction);
9884 9990
9885 debug_info->set_break_points(*new_break_points); 9991 debug_info->set_break_points(*new_break_points);
9886 for (int i = 0; i < old_break_points->length(); i++) { 9992 for (int i = 0; i < old_break_points->length(); i++) {
9887 new_break_points->set(i, old_break_points->get(i)); 9993 new_break_points->set(i, old_break_points->get(i));
9888 } 9994 }
9889 index = old_break_points->length(); 9995 index = old_break_points->length();
9890 } 9996 }
9891 ASSERT(index != kNoBreakPointInfo); 9997 ASSERT(index != kNoBreakPointInfo);
9892 9998
9893 // Allocate new BreakPointInfo object and set the break point. 9999 // Allocate new BreakPointInfo object and set the break point.
9894 Handle<BreakPointInfo> new_break_point_info = 10000 Handle<BreakPointInfo> new_break_point_info = Handle<BreakPointInfo>::cast(
9895 Handle<BreakPointInfo>::cast(Factory::NewStruct(BREAK_POINT_INFO_TYPE)); 10001 isolate->factory()->NewStruct(BREAK_POINT_INFO_TYPE));
9896 new_break_point_info->set_code_position(Smi::FromInt(code_position)); 10002 new_break_point_info->set_code_position(Smi::FromInt(code_position));
9897 new_break_point_info->set_source_position(Smi::FromInt(source_position)); 10003 new_break_point_info->set_source_position(Smi::FromInt(source_position));
9898 new_break_point_info-> 10004 new_break_point_info->
9899 set_statement_position(Smi::FromInt(statement_position)); 10005 set_statement_position(Smi::FromInt(statement_position));
9900 new_break_point_info->set_break_point_objects(Heap::undefined_value()); 10006 new_break_point_info->set_break_point_objects(
10007 isolate->heap()->undefined_value());
9901 BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object); 10008 BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object);
9902 debug_info->break_points()->set(index, *new_break_point_info); 10009 debug_info->break_points()->set(index, *new_break_point_info);
9903 } 10010 }
9904 10011
9905 10012
9906 // Get the break point objects for a code position. 10013 // Get the break point objects for a code position.
9907 Object* DebugInfo::GetBreakPointObjects(int code_position) { 10014 Object* DebugInfo::GetBreakPointObjects(int code_position) {
10015 Heap* heap = GetHeap();
9908 Object* break_point_info = GetBreakPointInfo(code_position); 10016 Object* break_point_info = GetBreakPointInfo(code_position);
9909 if (break_point_info->IsUndefined()) { 10017 if (break_point_info->IsUndefined()) {
9910 return Heap::undefined_value(); 10018 return heap->undefined_value();
9911 } 10019 }
9912 return BreakPointInfo::cast(break_point_info)->break_point_objects(); 10020 return BreakPointInfo::cast(break_point_info)->break_point_objects();
9913 } 10021 }
9914 10022
9915 10023
9916 // Get the total number of break points. 10024 // Get the total number of break points.
9917 int DebugInfo::GetBreakPointCount() { 10025 int DebugInfo::GetBreakPointCount() {
9918 if (break_points()->IsUndefined()) return 0; 10026 if (break_points()->IsUndefined()) return 0;
9919 int count = 0; 10027 int count = 0;
9920 for (int i = 0; i < break_points()->length(); i++) { 10028 for (int i = 0; i < break_points()->length(); i++) {
9921 if (!break_points()->get(i)->IsUndefined()) { 10029 if (!break_points()->get(i)->IsUndefined()) {
9922 BreakPointInfo* break_point_info = 10030 BreakPointInfo* break_point_info =
9923 BreakPointInfo::cast(break_points()->get(i)); 10031 BreakPointInfo::cast(break_points()->get(i));
9924 count += break_point_info->GetBreakPointCount(); 10032 count += break_point_info->GetBreakPointCount();
9925 } 10033 }
9926 } 10034 }
9927 return count; 10035 return count;
9928 } 10036 }
9929 10037
9930 10038
9931 Object* DebugInfo::FindBreakPointInfo(Handle<DebugInfo> debug_info, 10039 Object* DebugInfo::FindBreakPointInfo(Handle<DebugInfo> debug_info,
9932 Handle<Object> break_point_object) { 10040 Handle<Object> break_point_object) {
9933 if (debug_info->break_points()->IsUndefined()) return Heap::undefined_value(); 10041 Heap* heap = Isolate::Current()->heap();
10042 if (debug_info->break_points()->IsUndefined()) return heap->undefined_value();
9934 for (int i = 0; i < debug_info->break_points()->length(); i++) { 10043 for (int i = 0; i < debug_info->break_points()->length(); i++) {
9935 if (!debug_info->break_points()->get(i)->IsUndefined()) { 10044 if (!debug_info->break_points()->get(i)->IsUndefined()) {
9936 Handle<BreakPointInfo> break_point_info = 10045 Handle<BreakPointInfo> break_point_info =
9937 Handle<BreakPointInfo>(BreakPointInfo::cast( 10046 Handle<BreakPointInfo>(BreakPointInfo::cast(
9938 debug_info->break_points()->get(i))); 10047 debug_info->break_points()->get(i)));
9939 if (BreakPointInfo::HasBreakPointObject(break_point_info, 10048 if (BreakPointInfo::HasBreakPointObject(break_point_info,
9940 break_point_object)) { 10049 break_point_object)) {
9941 return *break_point_info; 10050 return *break_point_info;
9942 } 10051 }
9943 } 10052 }
9944 } 10053 }
9945 return Heap::undefined_value(); 10054 return heap->undefined_value();
9946 } 10055 }
9947 10056
9948 10057
9949 // Find the index of the break point info object for the specified code 10058 // Find the index of the break point info object for the specified code
9950 // position. 10059 // position.
9951 int DebugInfo::GetBreakPointInfoIndex(int code_position) { 10060 int DebugInfo::GetBreakPointInfoIndex(int code_position) {
9952 if (break_points()->IsUndefined()) return kNoBreakPointInfo; 10061 if (break_points()->IsUndefined()) return kNoBreakPointInfo;
9953 for (int i = 0; i < break_points()->length(); i++) { 10062 for (int i = 0; i < break_points()->length(); i++) {
9954 if (!break_points()->get(i)->IsUndefined()) { 10063 if (!break_points()->get(i)->IsUndefined()) {
9955 BreakPointInfo* break_point_info = 10064 BreakPointInfo* break_point_info =
9956 BreakPointInfo::cast(break_points()->get(i)); 10065 BreakPointInfo::cast(break_points()->get(i));
9957 if (break_point_info->code_position()->value() == code_position) { 10066 if (break_point_info->code_position()->value() == code_position) {
9958 return i; 10067 return i;
9959 } 10068 }
9960 } 10069 }
9961 } 10070 }
9962 return kNoBreakPointInfo; 10071 return kNoBreakPointInfo;
9963 } 10072 }
9964 10073
9965 10074
9966 // Remove the specified break point object. 10075 // Remove the specified break point object.
9967 void BreakPointInfo::ClearBreakPoint(Handle<BreakPointInfo> break_point_info, 10076 void BreakPointInfo::ClearBreakPoint(Handle<BreakPointInfo> break_point_info,
9968 Handle<Object> break_point_object) { 10077 Handle<Object> break_point_object) {
10078 Isolate* isolate = Isolate::Current();
9969 // If there are no break points just ignore. 10079 // If there are no break points just ignore.
9970 if (break_point_info->break_point_objects()->IsUndefined()) return; 10080 if (break_point_info->break_point_objects()->IsUndefined()) return;
9971 // If there is a single break point clear it if it is the same. 10081 // If there is a single break point clear it if it is the same.
9972 if (!break_point_info->break_point_objects()->IsFixedArray()) { 10082 if (!break_point_info->break_point_objects()->IsFixedArray()) {
9973 if (break_point_info->break_point_objects() == *break_point_object) { 10083 if (break_point_info->break_point_objects() == *break_point_object) {
9974 break_point_info->set_break_point_objects(Heap::undefined_value()); 10084 break_point_info->set_break_point_objects(
10085 isolate->heap()->undefined_value());
9975 } 10086 }
9976 return; 10087 return;
9977 } 10088 }
9978 // If there are multiple break points shrink the array 10089 // If there are multiple break points shrink the array
9979 ASSERT(break_point_info->break_point_objects()->IsFixedArray()); 10090 ASSERT(break_point_info->break_point_objects()->IsFixedArray());
9980 Handle<FixedArray> old_array = 10091 Handle<FixedArray> old_array =
9981 Handle<FixedArray>( 10092 Handle<FixedArray>(
9982 FixedArray::cast(break_point_info->break_point_objects())); 10093 FixedArray::cast(break_point_info->break_point_objects()));
9983 Handle<FixedArray> new_array = 10094 Handle<FixedArray> new_array =
9984 Factory::NewFixedArray(old_array->length() - 1); 10095 isolate->factory()->NewFixedArray(old_array->length() - 1);
9985 int found_count = 0; 10096 int found_count = 0;
9986 for (int i = 0; i < old_array->length(); i++) { 10097 for (int i = 0; i < old_array->length(); i++) {
9987 if (old_array->get(i) == *break_point_object) { 10098 if (old_array->get(i) == *break_point_object) {
9988 ASSERT(found_count == 0); 10099 ASSERT(found_count == 0);
9989 found_count++; 10100 found_count++;
9990 } else { 10101 } else {
9991 new_array->set(i - found_count, old_array->get(i)); 10102 new_array->set(i - found_count, old_array->get(i));
9992 } 10103 }
9993 } 10104 }
9994 // If the break point was found in the list change it. 10105 // If the break point was found in the list change it.
9995 if (found_count > 0) break_point_info->set_break_point_objects(*new_array); 10106 if (found_count > 0) break_point_info->set_break_point_objects(*new_array);
9996 } 10107 }
9997 10108
9998 10109
9999 // Add the specified break point object. 10110 // Add the specified break point object.
10000 void BreakPointInfo::SetBreakPoint(Handle<BreakPointInfo> break_point_info, 10111 void BreakPointInfo::SetBreakPoint(Handle<BreakPointInfo> break_point_info,
10001 Handle<Object> break_point_object) { 10112 Handle<Object> break_point_object) {
10002 // If there was no break point objects before just set it. 10113 // If there was no break point objects before just set it.
10003 if (break_point_info->break_point_objects()->IsUndefined()) { 10114 if (break_point_info->break_point_objects()->IsUndefined()) {
10004 break_point_info->set_break_point_objects(*break_point_object); 10115 break_point_info->set_break_point_objects(*break_point_object);
10005 return; 10116 return;
10006 } 10117 }
10007 // If the break point object is the same as before just ignore. 10118 // If the break point object is the same as before just ignore.
10008 if (break_point_info->break_point_objects() == *break_point_object) return; 10119 if (break_point_info->break_point_objects() == *break_point_object) return;
10009 // If there was one break point object before replace with array. 10120 // If there was one break point object before replace with array.
10010 if (!break_point_info->break_point_objects()->IsFixedArray()) { 10121 if (!break_point_info->break_point_objects()->IsFixedArray()) {
10011 Handle<FixedArray> array = Factory::NewFixedArray(2); 10122 Handle<FixedArray> array = FACTORY->NewFixedArray(2);
10012 array->set(0, break_point_info->break_point_objects()); 10123 array->set(0, break_point_info->break_point_objects());
10013 array->set(1, *break_point_object); 10124 array->set(1, *break_point_object);
10014 break_point_info->set_break_point_objects(*array); 10125 break_point_info->set_break_point_objects(*array);
10015 return; 10126 return;
10016 } 10127 }
10017 // If there was more than one break point before extend array. 10128 // If there was more than one break point before extend array.
10018 Handle<FixedArray> old_array = 10129 Handle<FixedArray> old_array =
10019 Handle<FixedArray>( 10130 Handle<FixedArray>(
10020 FixedArray::cast(break_point_info->break_point_objects())); 10131 FixedArray::cast(break_point_info->break_point_objects()));
10021 Handle<FixedArray> new_array = 10132 Handle<FixedArray> new_array =
10022 Factory::NewFixedArray(old_array->length() + 1); 10133 FACTORY->NewFixedArray(old_array->length() + 1);
10023 for (int i = 0; i < old_array->length(); i++) { 10134 for (int i = 0; i < old_array->length(); i++) {
10024 // If the break point was there before just ignore. 10135 // If the break point was there before just ignore.
10025 if (old_array->get(i) == *break_point_object) return; 10136 if (old_array->get(i) == *break_point_object) return;
10026 new_array->set(i, old_array->get(i)); 10137 new_array->set(i, old_array->get(i));
10027 } 10138 }
10028 // Add the new break point. 10139 // Add the new break point.
10029 new_array->set(old_array->length(), *break_point_object); 10140 new_array->set(old_array->length(), *break_point_object);
10030 break_point_info->set_break_point_objects(*new_array); 10141 break_point_info->set_break_point_objects(*new_array);
10031 } 10142 }
10032 10143
(...skipping 24 matching lines...) Expand all
10057 if (break_point_objects()->IsUndefined()) return 0; 10168 if (break_point_objects()->IsUndefined()) return 0;
10058 // Single beak point. 10169 // Single beak point.
10059 if (!break_point_objects()->IsFixedArray()) return 1; 10170 if (!break_point_objects()->IsFixedArray()) return 1;
10060 // Multiple break points. 10171 // Multiple break points.
10061 return FixedArray::cast(break_point_objects())->length(); 10172 return FixedArray::cast(break_point_objects())->length();
10062 } 10173 }
10063 #endif 10174 #endif
10064 10175
10065 10176
10066 } } // namespace v8::internal 10177 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698