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

Side by Side Diff: src/objects.cc

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

Powered by Google App Engine
This is Rietveld 408576698