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

Side by Side Diff: src/objects.cc

Issue 133443009: A64: Synchronize with r17441. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 10 matching lines...) Expand all
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "accessors.h" 30 #include "accessors.h"
31 #include "allocation-site-scopes.h"
31 #include "api.h" 32 #include "api.h"
32 #include "arguments.h" 33 #include "arguments.h"
33 #include "bootstrapper.h" 34 #include "bootstrapper.h"
34 #include "codegen.h" 35 #include "codegen.h"
35 #include "cpu-profiler.h" 36 #include "cpu-profiler.h"
36 #include "debug.h" 37 #include "debug.h"
37 #include "deoptimizer.h" 38 #include "deoptimizer.h"
38 #include "date.h" 39 #include "date.h"
39 #include "elements.h" 40 #include "elements.h"
40 #include "execution.h" 41 #include "execution.h"
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 } else { 136 } else {
136 result->isolate()->PushStackTraceAndDie( 137 result->isolate()->PushStackTraceAndDie(
137 0xDEAD0000, this, JSReceiver::cast(this)->map(), 0xDEAD0001); 138 0xDEAD0000, this, JSReceiver::cast(this)->map(), 0xDEAD0001);
138 } 139 }
139 } 140 }
140 ASSERT(holder != NULL); // Cannot handle null or undefined. 141 ASSERT(holder != NULL); // Cannot handle null or undefined.
141 JSReceiver::cast(holder)->Lookup(name, result); 142 JSReceiver::cast(holder)->Lookup(name, result);
142 } 143 }
143 144
144 145
146 Handle<Object> Object::GetPropertyWithReceiver(
147 Handle<Object> object,
148 Handle<Object> receiver,
149 Handle<Name> name,
150 PropertyAttributes* attributes) {
151 LookupResult lookup(name->GetIsolate());
152 object->Lookup(*name, &lookup);
153 Handle<Object> result =
154 GetProperty(object, receiver, &lookup, name, attributes);
155 ASSERT(*attributes <= ABSENT);
156 return result;
157 }
158
159
145 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, 160 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver,
146 Name* name, 161 Name* name,
147 PropertyAttributes* attributes) { 162 PropertyAttributes* attributes) {
148 LookupResult result(name->GetIsolate()); 163 LookupResult result(name->GetIsolate());
149 Lookup(name, &result); 164 Lookup(name, &result);
150 MaybeObject* value = GetProperty(receiver, &result, name, attributes); 165 MaybeObject* value = GetProperty(receiver, &result, name, attributes);
151 ASSERT(*attributes <= ABSENT); 166 ASSERT(*attributes <= ABSENT);
152 return value; 167 return value;
153 } 168 }
154 169
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 return GetPrimitiveValue(data->primitive_value_descriptor, 336 return GetPrimitiveValue(data->primitive_value_descriptor,
322 current, 337 current,
323 isolate->heap()); 338 isolate->heap());
324 } 339 }
325 } 340 }
326 UNREACHABLE(); 341 UNREACHABLE();
327 return NULL; 342 return NULL;
328 } 343 }
329 344
330 345
331 MaybeObject* JSObject::GetPropertyWithCallback(Object* receiver, 346 Handle<FixedArray> JSObject::EnsureWritableFastElements(
332 Object* structure, 347 Handle<JSObject> object) {
333 Name* name) { 348 CALL_HEAP_FUNCTION(object->GetIsolate(),
349 object->EnsureWritableFastElements(),
350 FixedArray);
351 }
352
353
354 Handle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
355 Handle<Object> receiver,
356 Handle<Object> structure,
357 Handle<Name> name) {
334 Isolate* isolate = name->GetIsolate(); 358 Isolate* isolate = name->GetIsolate();
335 // To accommodate both the old and the new api we switch on the 359 // To accommodate both the old and the new api we switch on the
336 // data structure used to store the callbacks. Eventually foreign 360 // data structure used to store the callbacks. Eventually foreign
337 // callbacks should be phased out. 361 // callbacks should be phased out.
338 if (structure->IsForeign()) { 362 if (structure->IsForeign()) {
339 AccessorDescriptor* callback = 363 AccessorDescriptor* callback =
340 reinterpret_cast<AccessorDescriptor*>( 364 reinterpret_cast<AccessorDescriptor*>(
341 Foreign::cast(structure)->foreign_address()); 365 Handle<Foreign>::cast(structure)->foreign_address());
342 MaybeObject* value = (callback->getter)(isolate, receiver, callback->data); 366 CALL_HEAP_FUNCTION(isolate,
343 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 367 (callback->getter)(isolate, *receiver, callback->data),
344 return value; 368 Object);
345 } 369 }
346 370
347 // api style callbacks. 371 // api style callbacks.
348 if (structure->IsAccessorInfo()) { 372 if (structure->IsAccessorInfo()) {
349 if (!AccessorInfo::cast(structure)->IsCompatibleReceiver(receiver)) { 373 Handle<AccessorInfo> accessor_info = Handle<AccessorInfo>::cast(structure);
350 Handle<Object> name_handle(name, isolate); 374 if (!accessor_info->IsCompatibleReceiver(*receiver)) {
351 Handle<Object> receiver_handle(receiver, isolate); 375 Handle<Object> args[2] = { name, receiver };
352 Handle<Object> args[2] = { name_handle, receiver_handle };
353 Handle<Object> error = 376 Handle<Object> error =
354 isolate->factory()->NewTypeError("incompatible_method_receiver", 377 isolate->factory()->NewTypeError("incompatible_method_receiver",
355 HandleVector(args, 378 HandleVector(args,
356 ARRAY_SIZE(args))); 379 ARRAY_SIZE(args)));
357 return isolate->Throw(*error); 380 isolate->Throw(*error);
381 return Handle<Object>::null();
358 } 382 }
359 // TODO(rossberg): Handling symbols in the API requires changing the API, 383 // TODO(rossberg): Handling symbols in the API requires changing the API,
360 // so we do not support it for now. 384 // so we do not support it for now.
361 if (name->IsSymbol()) return isolate->heap()->undefined_value(); 385 if (name->IsSymbol()) return isolate->factory()->undefined_value();
362 if (structure->IsDeclaredAccessorInfo()) { 386 if (structure->IsDeclaredAccessorInfo()) {
363 return GetDeclaredAccessorProperty(receiver, 387 CALL_HEAP_FUNCTION(
364 DeclaredAccessorInfo::cast(structure), 388 isolate,
365 isolate); 389 GetDeclaredAccessorProperty(*receiver,
390 DeclaredAccessorInfo::cast(*structure),
391 isolate),
392 Object);
366 } 393 }
367 ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(structure); 394
368 Object* fun_obj = data->getter(); 395 Handle<ExecutableAccessorInfo> data =
396 Handle<ExecutableAccessorInfo>::cast(structure);
369 v8::AccessorGetterCallback call_fun = 397 v8::AccessorGetterCallback call_fun =
370 v8::ToCData<v8::AccessorGetterCallback>(fun_obj); 398 v8::ToCData<v8::AccessorGetterCallback>(data->getter());
371 if (call_fun == NULL) return isolate->heap()->undefined_value(); 399 if (call_fun == NULL) return isolate->factory()->undefined_value();
400
372 HandleScope scope(isolate); 401 HandleScope scope(isolate);
373 JSObject* self = JSObject::cast(receiver); 402 Handle<JSObject> self = Handle<JSObject>::cast(receiver);
374 Handle<String> key(String::cast(name)); 403 Handle<String> key = Handle<String>::cast(name);
375 LOG(isolate, ApiNamedPropertyAccess("load", self, name)); 404 LOG(isolate, ApiNamedPropertyAccess("load", *self, *name));
376 PropertyCallbackArguments args(isolate, data->data(), self, this); 405 PropertyCallbackArguments args(isolate, data->data(), *self, *object);
377 v8::Handle<v8::Value> result = 406 v8::Handle<v8::Value> result =
378 args.Call(call_fun, v8::Utils::ToLocal(key)); 407 args.Call(call_fun, v8::Utils::ToLocal(key));
379 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 408 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
380 if (result.IsEmpty()) { 409 if (result.IsEmpty()) {
381 return isolate->heap()->undefined_value(); 410 return isolate->factory()->undefined_value();
382 } 411 }
383 Object* return_value = *v8::Utils::OpenHandle(*result); 412 Handle<Object> return_value = v8::Utils::OpenHandle(*result);
384 return_value->VerifyApiCallResultType(); 413 return_value->VerifyApiCallResultType();
385 return return_value; 414 return scope.CloseAndEscape(return_value);
386 } 415 }
387 416
388 // __defineGetter__ callback 417 // __defineGetter__ callback
389 if (structure->IsAccessorPair()) { 418 Handle<Object> getter(Handle<AccessorPair>::cast(structure)->getter(),
390 Object* getter = AccessorPair::cast(structure)->getter(); 419 isolate);
391 if (getter->IsSpecFunction()) { 420 if (getter->IsSpecFunction()) {
392 // TODO(rossberg): nicer would be to cast to some JSCallable here... 421 // TODO(rossberg): nicer would be to cast to some JSCallable here...
393 return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter)); 422 CALL_HEAP_FUNCTION(
394 } 423 isolate,
395 // Getter is not a function. 424 object->GetPropertyWithDefinedGetter(*receiver,
396 return isolate->heap()->undefined_value(); 425 JSReceiver::cast(*getter)),
426 Object);
397 } 427 }
398 428 // Getter is not a function.
399 UNREACHABLE(); 429 return isolate->factory()->undefined_value();
400 return NULL;
401 } 430 }
402 431
403 432
404 MaybeObject* JSProxy::GetPropertyWithHandler(Object* receiver_raw, 433 MaybeObject* JSProxy::GetPropertyWithHandler(Object* receiver_raw,
405 Name* name_raw) { 434 Name* name_raw) {
406 Isolate* isolate = GetIsolate(); 435 Isolate* isolate = GetIsolate();
407 HandleScope scope(isolate); 436 HandleScope scope(isolate);
408 Handle<Object> receiver(receiver_raw, isolate); 437 Handle<Object> receiver(receiver_raw, isolate);
409 Handle<Object> name(name_raw, isolate); 438 Handle<Object> name(name_raw, isolate);
410 439
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 bool has_pending_exception; 515 bool has_pending_exception;
487 Handle<Object> result = Execution::Call( 516 Handle<Object> result = Execution::Call(
488 isolate, fun, self, 0, NULL, &has_pending_exception, true); 517 isolate, fun, self, 0, NULL, &has_pending_exception, true);
489 // Check for pending exception and return the result. 518 // Check for pending exception and return the result.
490 if (has_pending_exception) return Failure::Exception(); 519 if (has_pending_exception) return Failure::Exception();
491 return *result; 520 return *result;
492 } 521 }
493 522
494 523
495 // Only deal with CALLBACKS and INTERCEPTOR 524 // Only deal with CALLBACKS and INTERCEPTOR
496 MaybeObject* JSObject::GetPropertyWithFailedAccessCheck( 525 Handle<Object> JSObject::GetPropertyWithFailedAccessCheck(
497 Object* receiver, 526 Handle<JSObject> object,
527 Handle<Object> receiver,
498 LookupResult* result, 528 LookupResult* result,
499 Name* name, 529 Handle<Name> name,
500 PropertyAttributes* attributes) { 530 PropertyAttributes* attributes) {
531 Isolate* isolate = name->GetIsolate();
501 if (result->IsProperty()) { 532 if (result->IsProperty()) {
502 switch (result->type()) { 533 switch (result->type()) {
503 case CALLBACKS: { 534 case CALLBACKS: {
504 // Only allow API accessors. 535 // Only allow API accessors.
505 Object* obj = result->GetCallbackObject(); 536 Handle<Object> callback_obj(result->GetCallbackObject(), isolate);
506 if (obj->IsAccessorInfo()) { 537 if (callback_obj->IsAccessorInfo()) {
507 AccessorInfo* info = AccessorInfo::cast(obj); 538 if (!AccessorInfo::cast(*callback_obj)->all_can_read()) break;
508 if (info->all_can_read()) { 539 *attributes = result->GetAttributes();
509 *attributes = result->GetAttributes(); 540 // Fall through to GetPropertyWithCallback.
510 return result->holder()->GetPropertyWithCallback( 541 } else if (callback_obj->IsAccessorPair()) {
511 receiver, result->GetCallbackObject(), name); 542 if (!AccessorPair::cast(*callback_obj)->all_can_read()) break;
512 } 543 // Fall through to GetPropertyWithCallback.
513 } else if (obj->IsAccessorPair()) { 544 } else {
514 AccessorPair* pair = AccessorPair::cast(obj); 545 break;
515 if (pair->all_can_read()) {
516 return result->holder()->GetPropertyWithCallback(
517 receiver, result->GetCallbackObject(), name);
518 }
519 } 546 }
520 break; 547 Handle<JSObject> holder(result->holder(), isolate);
548 return GetPropertyWithCallback(holder, receiver, callback_obj, name);
521 } 549 }
522 case NORMAL: 550 case NORMAL:
523 case FIELD: 551 case FIELD:
524 case CONSTANT: { 552 case CONSTANT: {
525 // Search ALL_CAN_READ accessors in prototype chain. 553 // Search ALL_CAN_READ accessors in prototype chain.
526 LookupResult r(GetIsolate()); 554 LookupResult r(isolate);
527 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); 555 result->holder()->LookupRealNamedPropertyInPrototypes(*name, &r);
528 if (r.IsProperty()) { 556 if (r.IsProperty()) {
529 return GetPropertyWithFailedAccessCheck(receiver, 557 return GetPropertyWithFailedAccessCheck(
530 &r, 558 object, receiver, &r, name, attributes);
531 name,
532 attributes);
533 } 559 }
534 break; 560 break;
535 } 561 }
536 case INTERCEPTOR: { 562 case INTERCEPTOR: {
537 // If the object has an interceptor, try real named properties. 563 // If the object has an interceptor, try real named properties.
538 // No access check in GetPropertyAttributeWithInterceptor. 564 // No access check in GetPropertyAttributeWithInterceptor.
539 LookupResult r(GetIsolate()); 565 LookupResult r(isolate);
540 result->holder()->LookupRealNamedProperty(name, &r); 566 result->holder()->LookupRealNamedProperty(*name, &r);
541 if (r.IsProperty()) { 567 if (r.IsProperty()) {
542 return GetPropertyWithFailedAccessCheck(receiver, 568 return GetPropertyWithFailedAccessCheck(
543 &r, 569 object, receiver, &r, name, attributes);
544 name,
545 attributes);
546 } 570 }
547 break; 571 break;
548 } 572 }
549 default: 573 default:
550 UNREACHABLE(); 574 UNREACHABLE();
551 } 575 }
552 } 576 }
553 577
554 // No accessible property found. 578 // No accessible property found.
555 *attributes = ABSENT; 579 *attributes = ABSENT;
556 Heap* heap = name->GetHeap(); 580 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_GET);
557 Isolate* isolate = heap->isolate(); 581 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
558 isolate->ReportFailedAccessCheck(this, v8::ACCESS_GET); 582 return isolate->factory()->undefined_value();
559 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
560 return heap->undefined_value();
561 } 583 }
562 584
563 585
564 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( 586 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
565 Object* receiver, 587 Object* receiver,
566 LookupResult* result, 588 LookupResult* result,
567 Name* name, 589 Name* name,
568 bool continue_search) { 590 bool continue_search) {
569 if (result->IsProperty()) { 591 if (result->IsProperty()) {
570 switch (result->type()) { 592 switch (result->type()) {
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 LookupResult* result, 818 LookupResult* result,
797 Handle<Name> key, 819 Handle<Name> key,
798 PropertyAttributes* attributes) { 820 PropertyAttributes* attributes) {
799 Isolate* isolate = result->isolate(); 821 Isolate* isolate = result->isolate();
800 CALL_HEAP_FUNCTION_PASS_EXCEPTION( 822 CALL_HEAP_FUNCTION_PASS_EXCEPTION(
801 isolate, 823 isolate,
802 object->GetProperty(*receiver, result, *key, attributes)); 824 object->GetProperty(*receiver, result, *key, attributes));
803 } 825 }
804 826
805 827
828 // TODO(yangguo): handlify this and get rid of.
806 MaybeObject* Object::GetProperty(Object* receiver, 829 MaybeObject* Object::GetProperty(Object* receiver,
807 LookupResult* result, 830 LookupResult* result,
808 Name* name, 831 Name* name,
809 PropertyAttributes* attributes) { 832 PropertyAttributes* attributes) {
810 Isolate* isolate = name->GetIsolate(); 833 Isolate* isolate = name->GetIsolate();
811 Heap* heap = isolate->heap(); 834 Heap* heap = isolate->heap();
812 835
813 #ifdef DEBUG 836 #ifdef DEBUG
814 // TODO(mstarzinger): Only because of the AssertNoContextChange, drop as soon 837 // TODO(mstarzinger): Only because of the AssertNoContextChange, drop as soon
815 // as this method has been fully handlified. 838 // as this method has been fully handlified.
(...skipping 18 matching lines...) Expand all
834 ASSERT(this != this->GetPrototype(isolate)); 857 ASSERT(this != this->GetPrototype(isolate));
835 for (Object* current = this; 858 for (Object* current = this;
836 true; 859 true;
837 current = current->GetPrototype(isolate)) { 860 current = current->GetPrototype(isolate)) {
838 if (current->IsAccessCheckNeeded()) { 861 if (current->IsAccessCheckNeeded()) {
839 // Check if we're allowed to read from the current object. Note 862 // Check if we're allowed to read from the current object. Note
840 // that even though we may not actually end up loading the named 863 // that even though we may not actually end up loading the named
841 // property from the current object, we still check that we have 864 // property from the current object, we still check that we have
842 // access to it. 865 // access to it.
843 JSObject* checked = JSObject::cast(current); 866 JSObject* checked = JSObject::cast(current);
844 if (!heap->isolate()->MayNamedAccess(checked, name, v8::ACCESS_GET)) { 867 if (!isolate->MayNamedAccess(checked, name, v8::ACCESS_GET)) {
845 return checked->GetPropertyWithFailedAccessCheck(receiver, 868 HandleScope scope(isolate);
846 result, 869 Handle<Object> value = JSObject::GetPropertyWithFailedAccessCheck(
847 name, 870 handle(checked, isolate),
848 attributes); 871 handle(receiver, isolate),
872 result,
873 handle(name, isolate),
874 attributes);
875 RETURN_IF_EMPTY_HANDLE(isolate, value);
876 return *value;
849 } 877 }
850 } 878 }
851 // Stop traversing the chain once we reach the last object in the 879 // Stop traversing the chain once we reach the last object in the
852 // chain; either the holder of the result or null in case of an 880 // chain; either the holder of the result or null in case of an
853 // absent property. 881 // absent property.
854 if (current == last) break; 882 if (current == last) break;
855 } 883 }
856 } 884 }
857 885
858 if (!result->IsProperty()) { 886 if (!result->IsProperty()) {
(...skipping 10 matching lines...) Expand all
869 case FIELD: { 897 case FIELD: {
870 MaybeObject* maybe_result = result->holder()->FastPropertyAt( 898 MaybeObject* maybe_result = result->holder()->FastPropertyAt(
871 result->representation(), 899 result->representation(),
872 result->GetFieldIndex().field_index()); 900 result->GetFieldIndex().field_index());
873 if (!maybe_result->To(&value)) return maybe_result; 901 if (!maybe_result->To(&value)) return maybe_result;
874 ASSERT(!value->IsTheHole() || result->IsReadOnly()); 902 ASSERT(!value->IsTheHole() || result->IsReadOnly());
875 return value->IsTheHole() ? heap->undefined_value() : value; 903 return value->IsTheHole() ? heap->undefined_value() : value;
876 } 904 }
877 case CONSTANT: 905 case CONSTANT:
878 return result->GetConstant(); 906 return result->GetConstant();
879 case CALLBACKS: 907 case CALLBACKS: {
880 return result->holder()->GetPropertyWithCallback( 908 HandleScope scope(isolate);
881 receiver, result->GetCallbackObject(), name); 909 Handle<Object> value = JSObject::GetPropertyWithCallback(
910 handle(result->holder(), isolate),
911 handle(receiver, isolate),
912 handle(result->GetCallbackObject(), isolate),
913 handle(name, isolate));
914 RETURN_IF_EMPTY_HANDLE(isolate, value);
915 return *value;
916 }
882 case HANDLER: 917 case HANDLER:
883 return result->proxy()->GetPropertyWithHandler(receiver, name); 918 return result->proxy()->GetPropertyWithHandler(receiver, name);
884 case INTERCEPTOR: 919 case INTERCEPTOR: {
885 return result->holder()->GetPropertyWithInterceptor( 920 HandleScope scope(isolate);
886 receiver, name, attributes); 921 Handle<Object> value = JSObject::GetPropertyWithInterceptor(
922 handle(result->holder(), isolate),
923 handle(receiver, isolate),
924 handle(name, isolate),
925 attributes);
926 RETURN_IF_EMPTY_HANDLE(isolate, value);
927 return *value;
928 }
887 case TRANSITION: 929 case TRANSITION:
888 case NONEXISTENT: 930 case NONEXISTENT:
889 UNREACHABLE(); 931 UNREACHABLE();
890 break; 932 break;
891 } 933 }
892 UNREACHABLE(); 934 UNREACHABLE();
893 return NULL; 935 return NULL;
894 } 936 }
895 937
896 938
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 default: 1197 default:
1156 return this; 1198 return this;
1157 } 1199 }
1158 } 1200 }
1159 1201
1160 1202
1161 bool String::MakeExternal(v8::String::ExternalStringResource* resource) { 1203 bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
1162 // Externalizing twice leaks the external resource, so it's 1204 // Externalizing twice leaks the external resource, so it's
1163 // prohibited by the API. 1205 // prohibited by the API.
1164 ASSERT(!this->IsExternalString()); 1206 ASSERT(!this->IsExternalString());
1165 #ifdef DEBUG 1207 #ifdef ENABLE_SLOW_ASSERTS
1166 if (FLAG_enable_slow_asserts) { 1208 if (FLAG_enable_slow_asserts) {
1167 // Assert that the resource and the string are equivalent. 1209 // Assert that the resource and the string are equivalent.
1168 ASSERT(static_cast<size_t>(this->length()) == resource->length()); 1210 ASSERT(static_cast<size_t>(this->length()) == resource->length());
1169 ScopedVector<uc16> smart_chars(this->length()); 1211 ScopedVector<uc16> smart_chars(this->length());
1170 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); 1212 String::WriteToFlat(this, smart_chars.start(), 0, this->length());
1171 ASSERT(memcmp(smart_chars.start(), 1213 ASSERT(memcmp(smart_chars.start(),
1172 resource->data(), 1214 resource->data(),
1173 resource->length() * sizeof(smart_chars[0])) == 0); 1215 resource->length() * sizeof(smart_chars[0])) == 0);
1174 } 1216 }
1175 #endif // DEBUG 1217 #endif // DEBUG
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); 1254 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size);
1213 if (Marking::IsBlack(Marking::MarkBitFrom(this))) { 1255 if (Marking::IsBlack(Marking::MarkBitFrom(this))) {
1214 MemoryChunk::IncrementLiveBytesFromMutator(this->address(), 1256 MemoryChunk::IncrementLiveBytesFromMutator(this->address(),
1215 new_size - size); 1257 new_size - size);
1216 } 1258 }
1217 return true; 1259 return true;
1218 } 1260 }
1219 1261
1220 1262
1221 bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) { 1263 bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) {
1222 #ifdef DEBUG 1264 #ifdef ENABLE_SLOW_ASSERTS
1223 if (FLAG_enable_slow_asserts) { 1265 if (FLAG_enable_slow_asserts) {
1224 // Assert that the resource and the string are equivalent. 1266 // Assert that the resource and the string are equivalent.
1225 ASSERT(static_cast<size_t>(this->length()) == resource->length()); 1267 ASSERT(static_cast<size_t>(this->length()) == resource->length());
1226 if (this->IsTwoByteRepresentation()) { 1268 if (this->IsTwoByteRepresentation()) {
1227 ScopedVector<uint16_t> smart_chars(this->length()); 1269 ScopedVector<uint16_t> smart_chars(this->length());
1228 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); 1270 String::WriteToFlat(this, smart_chars.start(), 0, this->length());
1229 ASSERT(String::IsOneByte(smart_chars.start(), this->length())); 1271 ASSERT(String::IsOneByte(smart_chars.start(), this->length()));
1230 } 1272 }
1231 ScopedVector<char> smart_chars(this->length()); 1273 ScopedVector<char> smart_chars(this->length());
1232 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); 1274 String::WriteToFlat(this, smart_chars.start(), 0, this->length());
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
1697 } 1739 }
1698 break; 1740 break;
1699 } 1741 }
1700 return; 1742 return;
1701 } 1743 }
1702 1744
1703 switch (type) { 1745 switch (type) {
1704 case FIXED_ARRAY_TYPE: 1746 case FIXED_ARRAY_TYPE:
1705 FixedArray::BodyDescriptor::IterateBody(this, object_size, v); 1747 FixedArray::BodyDescriptor::IterateBody(this, object_size, v);
1706 break; 1748 break;
1749 case CONSTANT_POOL_ARRAY_TYPE:
1750 reinterpret_cast<ConstantPoolArray*>(this)->ConstantPoolIterateBody(v);
1751 break;
1707 case FIXED_DOUBLE_ARRAY_TYPE: 1752 case FIXED_DOUBLE_ARRAY_TYPE:
1708 break; 1753 break;
1709 case JS_OBJECT_TYPE: 1754 case JS_OBJECT_TYPE:
1710 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: 1755 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
1711 case JS_GENERATOR_OBJECT_TYPE: 1756 case JS_GENERATOR_OBJECT_TYPE:
1712 case JS_MODULE_TYPE: 1757 case JS_MODULE_TYPE:
1713 case JS_VALUE_TYPE: 1758 case JS_VALUE_TYPE:
1714 case JS_DATE_TYPE: 1759 case JS_DATE_TYPE:
1715 case JS_ARRAY_TYPE: 1760 case JS_ARRAY_TYPE:
1716 case JS_ARRAY_BUFFER_TYPE: 1761 case JS_ARRAY_BUFFER_TYPE:
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
2093 } else { 2138 } else {
2094 // Normalize the object to prevent very large instance descriptors. 2139 // Normalize the object to prevent very large instance descriptors.
2095 // This eliminates unwanted N^2 allocation and lookup behavior. 2140 // This eliminates unwanted N^2 allocation and lookup behavior.
2096 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); 2141 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
2097 AddSlowProperty(object, name, value, attributes); 2142 AddSlowProperty(object, name, value, attributes);
2098 } 2143 }
2099 } else { 2144 } else {
2100 AddSlowProperty(object, name, value, attributes); 2145 AddSlowProperty(object, name, value, attributes);
2101 } 2146 }
2102 2147
2103 if (FLAG_harmony_observation && object->map()->is_observed()) { 2148 if (FLAG_harmony_observation &&
2149 object->map()->is_observed() &&
2150 *name != isolate->heap()->hidden_string()) {
2104 Handle<Object> old_value = isolate->factory()->the_hole_value(); 2151 Handle<Object> old_value = isolate->factory()->the_hole_value();
2105 EnqueueChangeRecord(object, "new", name, old_value); 2152 EnqueueChangeRecord(object, "new", name, old_value);
2106 } 2153 }
2107 2154
2108 return value; 2155 return value;
2109 } 2156 }
2110 2157
2111 2158
2112 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, 2159 void JSObject::EnqueueChangeRecord(Handle<JSObject> object,
2113 const char* type_str, 2160 const char* type_str,
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2244 elms->set_length(len - to_trim); 2291 elms->set_length(len - to_trim);
2245 2292
2246 // Maintain marking consistency for IncrementalMarking. 2293 // Maintain marking consistency for IncrementalMarking.
2247 if (Marking::IsBlack(Marking::MarkBitFrom(elms))) { 2294 if (Marking::IsBlack(Marking::MarkBitFrom(elms))) {
2248 if (trim_mode == FROM_GC) { 2295 if (trim_mode == FROM_GC) {
2249 MemoryChunk::IncrementLiveBytesFromGC(elms->address(), -size_delta); 2296 MemoryChunk::IncrementLiveBytesFromGC(elms->address(), -size_delta);
2250 } else { 2297 } else {
2251 MemoryChunk::IncrementLiveBytesFromMutator(elms->address(), -size_delta); 2298 MemoryChunk::IncrementLiveBytesFromMutator(elms->address(), -size_delta);
2252 } 2299 }
2253 } 2300 }
2301
2302 // The array may not be moved during GC,
2303 // and size has to be adjusted nevertheless.
2304 HeapProfiler* profiler = heap->isolate()->heap_profiler();
2305 if (profiler->is_tracking_allocations()) {
2306 profiler->UpdateObjectSizeEvent(elms->address(), elms->Size());
2307 }
2254 } 2308 }
2255 2309
2256 2310
2257 bool Map::InstancesNeedRewriting(Map* target, 2311 bool Map::InstancesNeedRewriting(Map* target,
2258 int target_number_of_fields, 2312 int target_number_of_fields,
2259 int target_inobject, 2313 int target_inobject,
2260 int target_unused) { 2314 int target_unused) {
2261 // If fields were added (or removed), rewrite the instance. 2315 // If fields were added (or removed), rewrite the instance.
2262 int number_of_fields = NumberOfFields(); 2316 int number_of_fields = NumberOfFields();
2263 ASSERT(target_number_of_fields >= number_of_fields); 2317 ASSERT(target_number_of_fields >= number_of_fields);
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
2381 // size and install the backing store into the object. 2435 // size and install the backing store into the object.
2382 if (external > 0) { 2436 if (external > 0) {
2383 RightTrimFixedArray<FROM_MUTATOR>(isolate->heap(), *array, inobject); 2437 RightTrimFixedArray<FROM_MUTATOR>(isolate->heap(), *array, inobject);
2384 object->set_properties(*array); 2438 object->set_properties(*array);
2385 } 2439 }
2386 2440
2387 object->set_map(*new_map); 2441 object->set_map(*new_map);
2388 } 2442 }
2389 2443
2390 2444
2445 Handle<TransitionArray> Map::AddTransition(Handle<Map> map,
2446 Handle<Name> key,
2447 Handle<Map> target,
2448 SimpleTransitionFlag flag) {
2449 CALL_HEAP_FUNCTION(map->GetIsolate(),
2450 map->AddTransition(*key, *target, flag),
2451 TransitionArray);
2452 }
2453
2454
2391 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, 2455 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object,
2392 int modify_index, 2456 int modify_index,
2393 Representation new_representation, 2457 Representation new_representation,
2394 StoreMode store_mode) { 2458 StoreMode store_mode) {
2395 Handle<Map> new_map = Map::GeneralizeRepresentation( 2459 Handle<Map> new_map = Map::GeneralizeRepresentation(
2396 handle(object->map()), modify_index, new_representation, store_mode); 2460 handle(object->map()), modify_index, new_representation, store_mode);
2397 if (object->map() == *new_map) return; 2461 if (object->map() == *new_map) return;
2398 return MigrateToMap(object, new_map); 2462 return MigrateToMap(object, new_map);
2399 } 2463 }
2400 2464
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
2681 for (; descriptor < descriptors; descriptor++) { 2745 for (; descriptor < descriptors; descriptor++) {
2682 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors); 2746 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors);
2683 new_map->set_migration_target(true); 2747 new_map->set_migration_target(true);
2684 } 2748 }
2685 2749
2686 new_map->set_owns_descriptors(true); 2750 new_map->set_owns_descriptors(true);
2687 return new_map; 2751 return new_map;
2688 } 2752 }
2689 2753
2690 2754
2755 // Generalize the representation of all FIELD descriptors.
2756 Handle<Map> Map::GeneralizeAllFieldRepresentations(
2757 Handle<Map> map,
2758 Representation new_representation) {
2759 Handle<DescriptorArray> descriptors(map->instance_descriptors());
2760 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
2761 PropertyDetails details = descriptors->GetDetails(i);
2762 if (details.type() == FIELD) {
2763 map = GeneralizeRepresentation(map, i, new_representation, FORCE_FIELD);
2764 }
2765 }
2766 return map;
2767 }
2768
2769
2691 Map* Map::CurrentMapForDeprecated() { 2770 Map* Map::CurrentMapForDeprecated() {
2692 DisallowHeapAllocation no_allocation; 2771 DisallowHeapAllocation no_allocation;
2693 if (!is_deprecated()) return this; 2772 if (!is_deprecated()) return this;
2694 2773
2695 DescriptorArray* old_descriptors = instance_descriptors(); 2774 DescriptorArray* old_descriptors = instance_descriptors();
2696 2775
2697 int descriptors = NumberOfOwnDescriptors(); 2776 int descriptors = NumberOfOwnDescriptors();
2698 Map* root_map = FindRootMap(); 2777 Map* root_map = FindRootMap();
2699 2778
2700 // Check the state of the root map. 2779 // Check the state of the root map.
(...skipping 1263 matching lines...) Expand 10 before | Expand all | Expand 10 after
3964 Handle<Object> error = isolate->factory()->NewTypeError( 4043 Handle<Object> error = isolate->factory()->NewTypeError(
3965 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); 4044 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
3966 isolate->Throw(*error); 4045 isolate->Throw(*error);
3967 return Handle<Object>(); 4046 return Handle<Object>();
3968 } else { 4047 } else {
3969 return value; 4048 return value;
3970 } 4049 }
3971 } 4050 }
3972 4051
3973 Handle<Object> old_value = isolate->factory()->the_hole_value(); 4052 Handle<Object> old_value = isolate->factory()->the_hole_value();
3974 if (FLAG_harmony_observation && 4053 bool is_observed = FLAG_harmony_observation &&
3975 object->map()->is_observed() && lookup->IsDataProperty()) { 4054 object->map()->is_observed() &&
4055 *name != isolate->heap()->hidden_string();
4056 if (is_observed && lookup->IsDataProperty()) {
3976 old_value = Object::GetProperty(object, name); 4057 old_value = Object::GetProperty(object, name);
3977 } 4058 }
3978 4059
3979 // This is a real property that is not read-only, or it is a 4060 // This is a real property that is not read-only, or it is a
3980 // transition or null descriptor and there are no setters in the prototypes. 4061 // transition or null descriptor and there are no setters in the prototypes.
3981 Handle<Object> result = value; 4062 Handle<Object> result = value;
3982 switch (lookup->type()) { 4063 switch (lookup->type()) {
3983 case NORMAL: 4064 case NORMAL:
3984 SetNormalizedProperty(handle(lookup->holder()), lookup, value); 4065 SetNormalizedProperty(handle(lookup->holder()), lookup, value);
3985 break; 4066 break;
(...skipping 18 matching lines...) Expand all
4004 result = SetPropertyUsingTransition(handle(lookup->holder()), lookup, 4085 result = SetPropertyUsingTransition(handle(lookup->holder()), lookup,
4005 name, value, attributes); 4086 name, value, attributes);
4006 break; 4087 break;
4007 case HANDLER: 4088 case HANDLER:
4008 case NONEXISTENT: 4089 case NONEXISTENT:
4009 UNREACHABLE(); 4090 UNREACHABLE();
4010 } 4091 }
4011 4092
4012 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>()); 4093 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>());
4013 4094
4014 if (FLAG_harmony_observation && object->map()->is_observed()) { 4095 if (is_observed) {
4015 if (lookup->IsTransition()) { 4096 if (lookup->IsTransition()) {
4016 EnqueueChangeRecord(object, "new", name, old_value); 4097 EnqueueChangeRecord(object, "new", name, old_value);
4017 } else { 4098 } else {
4018 LookupResult new_lookup(isolate); 4099 LookupResult new_lookup(isolate);
4019 object->LocalLookup(*name, &new_lookup, true); 4100 object->LocalLookup(*name, &new_lookup, true);
4020 if (new_lookup.IsDataProperty()) { 4101 if (new_lookup.IsDataProperty()) {
4021 Handle<Object> new_value = Object::GetProperty(object, name); 4102 Handle<Object> new_value = Object::GetProperty(object, name);
4022 if (!new_value->SameValue(*old_value)) { 4103 if (!new_value->SameValue(*old_value)) {
4023 EnqueueChangeRecord(object, "updated", name, old_value); 4104 EnqueueChangeRecord(object, "updated", name, old_value);
4024 } 4105 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
4105 4186
4106 // Check for accessor in prototype chain removed here in clone. 4187 // Check for accessor in prototype chain removed here in clone.
4107 if (!lookup.IsFound()) { 4188 if (!lookup.IsFound()) {
4108 // Neither properties nor transitions found. 4189 // Neither properties nor transitions found.
4109 return AddProperty(object, name, value, attributes, kNonStrictMode, 4190 return AddProperty(object, name, value, attributes, kNonStrictMode,
4110 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode); 4191 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode);
4111 } 4192 }
4112 4193
4113 Handle<Object> old_value = isolate->factory()->the_hole_value(); 4194 Handle<Object> old_value = isolate->factory()->the_hole_value();
4114 PropertyAttributes old_attributes = ABSENT; 4195 PropertyAttributes old_attributes = ABSENT;
4115 bool is_observed = FLAG_harmony_observation && object->map()->is_observed(); 4196 bool is_observed = FLAG_harmony_observation &&
4197 object->map()->is_observed() &&
4198 *name != isolate->heap()->hidden_string();
4116 if (is_observed && lookup.IsProperty()) { 4199 if (is_observed && lookup.IsProperty()) {
4117 if (lookup.IsDataProperty()) old_value = 4200 if (lookup.IsDataProperty()) old_value =
4118 Object::GetProperty(object, name); 4201 Object::GetProperty(object, name);
4119 old_attributes = lookup.GetAttributes(); 4202 old_attributes = lookup.GetAttributes();
4120 } 4203 }
4121 4204
4122 // Check of IsReadOnly removed from here in clone. 4205 // Check of IsReadOnly removed from here in clone.
4123 switch (lookup.type()) { 4206 switch (lookup.type()) {
4124 case NORMAL: 4207 case NORMAL:
4125 ReplaceSlowProperty(object, name, value, attributes); 4208 ReplaceSlowProperty(object, name, value, attributes);
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
4391 } 4474 }
4392 if (pt->IsNull()) return ABSENT; 4475 if (pt->IsNull()) return ABSENT;
4393 return JSObject::cast(pt)->GetElementAttributeWithReceiver( 4476 return JSObject::cast(pt)->GetElementAttributeWithReceiver(
4394 receiver, index, true); 4477 receiver, index, true);
4395 } 4478 }
4396 4479
4397 4480
4398 Handle<Map> NormalizedMapCache::Get(Handle<NormalizedMapCache> cache, 4481 Handle<Map> NormalizedMapCache::Get(Handle<NormalizedMapCache> cache,
4399 Handle<JSObject> obj, 4482 Handle<JSObject> obj,
4400 PropertyNormalizationMode mode) { 4483 PropertyNormalizationMode mode) {
4401 Map* fast = obj->map(); 4484 int index = obj->map()->Hash() % kEntries;
4402 int index = fast->Hash() % kEntries; 4485 Handle<Object> result = handle(cache->get(index), cache->GetIsolate());
4403 Object* result = cache->get(index);
4404 if (result->IsMap() && 4486 if (result->IsMap() &&
4405 Map::cast(result)->EquivalentToForNormalization(fast, mode)) { 4487 Handle<Map>::cast(result)->EquivalentToForNormalization(obj->map(),
4488 mode)) {
4406 #ifdef VERIFY_HEAP 4489 #ifdef VERIFY_HEAP
4407 if (FLAG_verify_heap) { 4490 if (FLAG_verify_heap) {
4408 Map::cast(result)->SharedMapVerify(); 4491 Handle<Map>::cast(result)->SharedMapVerify();
4409 } 4492 }
4410 #endif 4493 #endif
4411 #ifdef DEBUG 4494 #ifdef ENABLE_SLOW_ASSERTS
4412 if (FLAG_enable_slow_asserts) { 4495 if (FLAG_enable_slow_asserts) {
4413 // The cached map should match newly created normalized map bit-by-bit, 4496 // The cached map should match newly created normalized map bit-by-bit,
4414 // except for the code cache, which can contain some ics which can be 4497 // except for the code cache, which can contain some ics which can be
4415 // applied to the shared map. 4498 // applied to the shared map.
4416 Object* fresh; 4499 Handle<Map> fresh = Map::CopyNormalized(handle(obj->map()), mode,
4417 MaybeObject* maybe_fresh = 4500 SHARED_NORMALIZED_MAP);
4418 fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP); 4501
4419 if (maybe_fresh->ToObject(&fresh)) { 4502 ASSERT(memcmp(fresh->address(),
4420 ASSERT(memcmp(Map::cast(fresh)->address(), 4503 Handle<Map>::cast(result)->address(),
4421 Map::cast(result)->address(), 4504 Map::kCodeCacheOffset) == 0);
4422 Map::kCodeCacheOffset) == 0); 4505 STATIC_ASSERT(Map::kDependentCodeOffset ==
4423 STATIC_ASSERT(Map::kDependentCodeOffset == 4506 Map::kCodeCacheOffset + kPointerSize);
4424 Map::kCodeCacheOffset + kPointerSize); 4507 int offset = Map::kDependentCodeOffset + kPointerSize;
4425 int offset = Map::kDependentCodeOffset + kPointerSize; 4508 ASSERT(memcmp(fresh->address() + offset,
4426 ASSERT(memcmp(Map::cast(fresh)->address() + offset, 4509 Handle<Map>::cast(result)->address() + offset,
4427 Map::cast(result)->address() + offset, 4510 Map::kSize - offset) == 0);
4428 Map::kSize - offset) == 0);
4429 }
4430 } 4511 }
4431 #endif 4512 #endif
4432 return handle(Map::cast(result)); 4513 return Handle<Map>::cast(result);
4433 } 4514 }
4434 4515
4435 Isolate* isolate = cache->GetIsolate(); 4516 Isolate* isolate = cache->GetIsolate();
4436 Handle<Map> map = Map::CopyNormalized(handle(fast), mode, 4517 Handle<Map> map = Map::CopyNormalized(handle(obj->map()), mode,
4437 SHARED_NORMALIZED_MAP); 4518 SHARED_NORMALIZED_MAP);
4438 ASSERT(map->is_dictionary_map()); 4519 ASSERT(map->is_dictionary_map());
4439 cache->set(index, *map); 4520 cache->set(index, *map);
4440 isolate->counters()->normalized_maps()->Increment(); 4521 isolate->counters()->normalized_maps()->Increment();
4441 4522
4442 return map; 4523 return map;
4443 } 4524 }
4444 4525
4445 4526
4446 void NormalizedMapCache::Clear() { 4527 void NormalizedMapCache::Clear() {
(...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after
5169 Handle<Object> args[2] = { name, object }; 5250 Handle<Object> args[2] = { name, object };
5170 Handle<Object> error = isolate->factory()->NewTypeError( 5251 Handle<Object> error = isolate->factory()->NewTypeError(
5171 "strict_delete_property", HandleVector(args, ARRAY_SIZE(args))); 5252 "strict_delete_property", HandleVector(args, ARRAY_SIZE(args)));
5172 isolate->Throw(*error); 5253 isolate->Throw(*error);
5173 return Handle<Object>(); 5254 return Handle<Object>();
5174 } 5255 }
5175 return isolate->factory()->false_value(); 5256 return isolate->factory()->false_value();
5176 } 5257 }
5177 5258
5178 Handle<Object> old_value = isolate->factory()->the_hole_value(); 5259 Handle<Object> old_value = isolate->factory()->the_hole_value();
5179 bool is_observed = FLAG_harmony_observation && object->map()->is_observed(); 5260 bool is_observed = FLAG_harmony_observation &&
5261 object->map()->is_observed() &&
5262 *name != isolate->heap()->hidden_string();
5180 if (is_observed && lookup.IsDataProperty()) { 5263 if (is_observed && lookup.IsDataProperty()) {
5181 old_value = Object::GetProperty(object, name); 5264 old_value = Object::GetProperty(object, name);
5182 } 5265 }
5183 Handle<Object> result; 5266 Handle<Object> result;
5184 5267
5185 // Check for interceptor. 5268 // Check for interceptor.
5186 if (lookup.IsInterceptor()) { 5269 if (lookup.IsInterceptor()) {
5187 // Skip interceptor if forcing a deletion. 5270 // Skip interceptor if forcing a deletion.
5188 if (mode == FORCE_DELETION) { 5271 if (mode == FORCE_DELETION) {
5189 result = DeletePropertyPostInterceptor(object, name, mode); 5272 result = DeletePropertyPostInterceptor(object, name, mode);
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
5531 // Make sure we never go back to the fast case 5614 // Make sure we never go back to the fast case
5532 dictionary->set_requires_slow_elements(); 5615 dictionary->set_requires_slow_elements();
5533 // Freeze all elements in the dictionary 5616 // Freeze all elements in the dictionary
5534 FreezeDictionary(dictionary); 5617 FreezeDictionary(dictionary);
5535 } 5618 }
5536 5619
5537 return object; 5620 return object;
5538 } 5621 }
5539 5622
5540 5623
5541 MUST_USE_RESULT MaybeObject* JSObject::SetObserved(Isolate* isolate) { 5624 void JSObject::SetObserved(Handle<JSObject> object) {
5542 if (map()->is_observed()) 5625 Isolate* isolate = object->GetIsolate();
5543 return isolate->heap()->undefined_value();
5544 5626
5545 Heap* heap = isolate->heap(); 5627 if (object->map()->is_observed())
5628 return;
5546 5629
5547 if (!HasExternalArrayElements()) { 5630 if (!object->HasExternalArrayElements()) {
5548 // Go to dictionary mode, so that we don't skip map checks. 5631 // Go to dictionary mode, so that we don't skip map checks.
5549 MaybeObject* maybe = NormalizeElements(); 5632 NormalizeElements(object);
5550 if (maybe->IsFailure()) return maybe; 5633 ASSERT(!object->HasFastElements());
5551 ASSERT(!HasFastElements());
5552 } 5634 }
5553 5635
5554 LookupResult result(isolate); 5636 LookupResult result(isolate);
5555 map()->LookupTransition(this, heap->observed_symbol(), &result); 5637 object->map()->LookupTransition(*object,
5638 isolate->heap()->observed_symbol(),
5639 &result);
5556 5640
5557 Map* new_map; 5641 Handle<Map> new_map;
5558 if (result.IsTransition()) { 5642 if (result.IsTransition()) {
5559 new_map = result.GetTransitionTarget(); 5643 new_map = handle(result.GetTransitionTarget());
5560 ASSERT(new_map->is_observed()); 5644 ASSERT(new_map->is_observed());
5561 } else if (map()->CanHaveMoreTransitions()) { 5645 } else if (object->map()->CanHaveMoreTransitions()) {
5562 MaybeObject* maybe_new_map = map()->CopyForObserved(); 5646 new_map = Map::CopyForObserved(handle(object->map()));
5563 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
5564 } else { 5647 } else {
5565 MaybeObject* maybe_copy = map()->Copy(); 5648 new_map = Map::Copy(handle(object->map()));
5566 if (!maybe_copy->To(&new_map)) return maybe_copy;
5567 new_map->set_is_observed(true); 5649 new_map->set_is_observed(true);
5568 } 5650 }
5569 set_map(new_map); 5651 object->set_map(*new_map);
5570
5571 return heap->undefined_value();
5572 } 5652 }
5573 5653
5574 5654
5655 Handle<JSObject> JSObject::Copy(Handle<JSObject> object,
5656 Handle<AllocationSite> site) {
5657 Isolate* isolate = object->GetIsolate();
5658 CALL_HEAP_FUNCTION(isolate,
5659 isolate->heap()->CopyJSObject(*object, *site), JSObject);
5660 }
5661
5662
5575 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) { 5663 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) {
5576 Isolate* isolate = object->GetIsolate(); 5664 Isolate* isolate = object->GetIsolate();
5577 CALL_HEAP_FUNCTION(isolate, 5665 CALL_HEAP_FUNCTION(isolate,
5578 isolate->heap()->CopyJSObject(*object), JSObject); 5666 isolate->heap()->CopyJSObject(*object), JSObject);
5579 } 5667 }
5580 5668
5581 5669
5582 class JSObjectWalkVisitor { 5670 class JSObjectWalkVisitor {
5583 public: 5671 public:
5584 explicit JSObjectWalkVisitor() {} 5672 explicit JSObjectWalkVisitor(AllocationSiteContext* site_context) :
5673 site_context_(site_context) {}
5585 virtual ~JSObjectWalkVisitor() {} 5674 virtual ~JSObjectWalkVisitor() {}
5586 5675
5587 Handle<JSObject> Visit(Handle<JSObject> object) { 5676 Handle<JSObject> Visit(Handle<JSObject> object) {
5588 return StructureWalk(object); 5677 return StructureWalk(object);
5589 } 5678 }
5590 5679
5591 // Returns true if the visitor is a copying visitor.
5592 virtual bool is_copying() = 0; 5680 virtual bool is_copying() = 0;
5593 5681
5594 protected: 5682 protected:
5595 Handle<JSObject> StructureWalk(Handle<JSObject> object); 5683 Handle<JSObject> StructureWalk(Handle<JSObject> object);
5596 5684
5597 // The returned handle should point to a new object if the visitor is a 5685 // The returned handle will be used for the object in all subsequent usages.
5598 // copying visitor, otherwise it should be the same as the input object. 5686 // This allows VisitObject to make a copy of the object if desired.
5599 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) = 0; 5687 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) = 0;
5600
5601 // The returned handle should point to a new value if the visitor is a
5602 // copying visitor, otherwise it should be the same as the input value.
5603 virtual Handle<JSObject> VisitElementOrProperty(Handle<JSObject> object, 5688 virtual Handle<JSObject> VisitElementOrProperty(Handle<JSObject> object,
5604 Handle<JSObject> value) = 0; 5689 Handle<JSObject> value) = 0;
5690
5691 AllocationSiteContext* site_context() { return site_context_; }
5692
5693 private:
5694 AllocationSiteContext* site_context_;
5605 }; 5695 };
5606 5696
5607 5697
5608 class JSObjectCopyVisitor: public JSObjectWalkVisitor { 5698 class JSObjectCopyVisitor: public JSObjectWalkVisitor {
5609 public: 5699 public:
5610 explicit JSObjectCopyVisitor() {} 5700 explicit JSObjectCopyVisitor(AllocationSiteContext* site_context)
5701 : JSObjectWalkVisitor(site_context) {}
5611 5702
5612 virtual bool is_copying() V8_OVERRIDE { return true; } 5703 virtual bool is_copying() V8_OVERRIDE { return true; }
5613 5704
5614 protected: 5705 // The returned handle will be used for the object in all
5706 // subsequent usages. This allows VisitObject to make a copy
5707 // of the object if desired.
5615 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE { 5708 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE {
5616 return JSObject::Copy(object); 5709 // Only create a memento if
5710 // 1) we have a JSArray, and
5711 // 2) the elements kind is palatable
5712 // 3) allow_mementos is true
5713 Handle<JSObject> copy;
5714 if (site_context()->activated() &&
5715 AllocationSite::CanTrack(object->map()->instance_type()) &&
5716 AllocationSite::GetMode(object->GetElementsKind()) ==
5717 TRACK_ALLOCATION_SITE) {
5718 copy = JSObject::Copy(object, site_context()->current());
5719 } else {
5720 copy = JSObject::Copy(object);
5721 }
5722
5723 return copy;
5617 } 5724 }
5618 5725
5619 virtual Handle<JSObject> VisitElementOrProperty( 5726 virtual Handle<JSObject> VisitElementOrProperty(
5620 Handle<JSObject> object, 5727 Handle<JSObject> object,
5621 Handle<JSObject> value) V8_OVERRIDE { 5728 Handle<JSObject> value) V8_OVERRIDE {
5622 return StructureWalk(value); 5729 Handle<AllocationSite> current_site = site_context()->EnterNewScope();
5730 Handle<JSObject> copy_of_value = StructureWalk(value);
5731 site_context()->ExitScope(current_site, value);
5732 return copy_of_value;
5623 } 5733 }
5624 }; 5734 };
5625 5735
5736
5737 class JSObjectCreateAllocationSitesVisitor: public JSObjectWalkVisitor {
5738 public:
5739 explicit JSObjectCreateAllocationSitesVisitor(
5740 AllocationSiteContext* site_context)
5741 : JSObjectWalkVisitor(site_context) {}
5742
5743 virtual bool is_copying() V8_OVERRIDE { return false; }
5744
5745 // The returned handle will be used for the object in all
5746 // subsequent usages. This allows VisitObject to make a copy
5747 // of the object if desired.
5748 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE {
5749 return object;
5750 }
5751
5752 virtual Handle<JSObject> VisitElementOrProperty(
5753 Handle<JSObject> object,
5754 Handle<JSObject> value) V8_OVERRIDE {
5755 Handle<AllocationSite> current_site = site_context()->EnterNewScope();
5756 value = StructureWalk(value);
5757 site_context()->ExitScope(current_site, value);
5758 return value;
5759 }
5760 };
5761
5626 5762
5627 Handle<JSObject> JSObjectWalkVisitor::StructureWalk(Handle<JSObject> object) { 5763 Handle<JSObject> JSObjectWalkVisitor::StructureWalk(Handle<JSObject> object) {
5628 bool copying = is_copying(); 5764 bool copying = is_copying();
5629 Isolate* isolate = object->GetIsolate(); 5765 Isolate* isolate = object->GetIsolate();
5630 StackLimitCheck check(isolate); 5766 StackLimitCheck check(isolate);
5631 if (check.HasOverflowed()) { 5767 if (check.HasOverflowed()) {
5632 isolate->StackOverflow(); 5768 isolate->StackOverflow();
5633 return Handle<JSObject>::null(); 5769 return Handle<JSObject>::null();
5634 } 5770 }
5635 5771
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
5759 case EXTERNAL_DOUBLE_ELEMENTS: 5895 case EXTERNAL_DOUBLE_ELEMENTS:
5760 case FAST_DOUBLE_ELEMENTS: 5896 case FAST_DOUBLE_ELEMENTS:
5761 case FAST_HOLEY_DOUBLE_ELEMENTS: 5897 case FAST_HOLEY_DOUBLE_ELEMENTS:
5762 // No contained objects, nothing to do. 5898 // No contained objects, nothing to do.
5763 break; 5899 break;
5764 } 5900 }
5765 return copy; 5901 return copy;
5766 } 5902 }
5767 5903
5768 5904
5769 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) { 5905 Handle<JSObject> JSObject::DeepWalk(Handle<JSObject> object,
5770 JSObjectCopyVisitor v; 5906 AllocationSiteContext* site_context) {
5907 JSObjectCreateAllocationSitesVisitor v(site_context);
5908 Handle<JSObject> result = v.Visit(object);
5909 ASSERT(!v.is_copying() &&
5910 (result.is_null() || result.is_identical_to(object)));
5911 return result;
5912 }
5913
5914
5915 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object,
5916 AllocationSiteContext* site_context) {
5917 JSObjectCopyVisitor v(site_context);
5771 Handle<JSObject> copy = v.Visit(object); 5918 Handle<JSObject> copy = v.Visit(object);
5772 ASSERT(v.is_copying() && !copy.is_identical_to(object)); 5919 ASSERT(v.is_copying() && !copy.is_identical_to(object));
5773 return copy; 5920 return copy;
5774 } 5921 }
5775 5922
5776 5923
5777 // Tests for the fast common case for property enumeration: 5924 // Tests for the fast common case for property enumeration:
5778 // - This object and all prototypes has an enum cache (which means that 5925 // - This object and all prototypes has an enum cache (which means that
5779 // it is no proxy, has no interceptors and needs no access checks). 5926 // it is no proxy, has no interceptors and needs no access checks).
5780 // - This object has no elements. 5927 // - This object has no elements.
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
6177 6324
6178 // Try to flatten before operating on the string. 6325 // Try to flatten before operating on the string.
6179 if (name->IsString()) String::cast(*name)->TryFlatten(); 6326 if (name->IsString()) String::cast(*name)->TryFlatten();
6180 6327
6181 if (!object->CanSetCallback(*name)) return; 6328 if (!object->CanSetCallback(*name)) return;
6182 6329
6183 uint32_t index = 0; 6330 uint32_t index = 0;
6184 bool is_element = name->AsArrayIndex(&index); 6331 bool is_element = name->AsArrayIndex(&index);
6185 6332
6186 Handle<Object> old_value = isolate->factory()->the_hole_value(); 6333 Handle<Object> old_value = isolate->factory()->the_hole_value();
6187 bool is_observed = FLAG_harmony_observation && object->map()->is_observed(); 6334 bool is_observed = FLAG_harmony_observation &&
6335 object->map()->is_observed() &&
6336 *name != isolate->heap()->hidden_string();
6188 bool preexists = false; 6337 bool preexists = false;
6189 if (is_observed) { 6338 if (is_observed) {
6190 if (is_element) { 6339 if (is_element) {
6191 preexists = HasLocalElement(object, index); 6340 preexists = HasLocalElement(object, index);
6192 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) { 6341 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) {
6193 old_value = Object::GetElement(isolate, object, index); 6342 old_value = Object::GetElement(isolate, object, index);
6194 } 6343 }
6195 } else { 6344 } else {
6196 LookupResult lookup(isolate); 6345 LookupResult lookup(isolate);
6197 object->LocalLookup(*name, &lookup, true); 6346 object->LocalLookup(*name, &lookup, true);
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
6432 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_HAS)) { 6581 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_HAS)) {
6433 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS); 6582 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS);
6434 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); 6583 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
6435 return isolate->factory()->undefined_value(); 6584 return isolate->factory()->undefined_value();
6436 } 6585 }
6437 6586
6438 // Make the lookup and include prototypes. 6587 // Make the lookup and include prototypes.
6439 uint32_t index = 0; 6588 uint32_t index = 0;
6440 if (name->AsArrayIndex(&index)) { 6589 if (name->AsArrayIndex(&index)) {
6441 for (Handle<Object> obj = object; 6590 for (Handle<Object> obj = object;
6442 *obj != isolate->heap()->null_value(); 6591 !obj->IsNull();
6443 obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) { 6592 obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) {
6444 if (obj->IsJSObject() && JSObject::cast(*obj)->HasDictionaryElements()) { 6593 if (obj->IsJSObject() && JSObject::cast(*obj)->HasDictionaryElements()) {
6445 JSObject* js_object = JSObject::cast(*obj); 6594 JSObject* js_object = JSObject::cast(*obj);
6446 SeededNumberDictionary* dictionary = js_object->element_dictionary(); 6595 SeededNumberDictionary* dictionary = js_object->element_dictionary();
6447 int entry = dictionary->FindEntry(index); 6596 int entry = dictionary->FindEntry(index);
6448 if (entry != SeededNumberDictionary::kNotFound) { 6597 if (entry != SeededNumberDictionary::kNotFound) {
6449 Object* element = dictionary->ValueAt(entry); 6598 Object* element = dictionary->ValueAt(entry);
6450 if (dictionary->DetailsAt(entry).type() == CALLBACKS && 6599 if (dictionary->DetailsAt(entry).type() == CALLBACKS &&
6451 element->IsAccessorPair()) { 6600 element->IsAccessorPair()) {
6452 return handle(AccessorPair::cast(element)->GetComponent(component), 6601 return handle(AccessorPair::cast(element)->GetComponent(component),
6453 isolate); 6602 isolate);
6454 } 6603 }
6455 } 6604 }
6456 } 6605 }
6457 } 6606 }
6458 } else { 6607 } else {
6459 for (Handle<Object> obj = object; 6608 for (Handle<Object> obj = object;
6460 *obj != isolate->heap()->null_value(); 6609 !obj->IsNull();
6461 obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) { 6610 obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) {
6462 LookupResult result(isolate); 6611 LookupResult result(isolate);
6463 JSReceiver::cast(*obj)->LocalLookup(*name, &result); 6612 JSReceiver::cast(*obj)->LocalLookup(*name, &result);
6464 if (result.IsFound()) { 6613 if (result.IsFound()) {
6465 if (result.IsReadOnly()) return isolate->factory()->undefined_value(); 6614 if (result.IsReadOnly()) return isolate->factory()->undefined_value();
6466 if (result.IsPropertyCallbacks()) { 6615 if (result.IsPropertyCallbacks()) {
6467 Object* obj = result.GetCallbackObject(); 6616 Object* obj = result.GetCallbackObject();
6468 if (obj->IsAccessorPair()) { 6617 if (obj->IsAccessorPair()) {
6469 return handle(AccessorPair::cast(obj)->GetComponent(component), 6618 return handle(AccessorPair::cast(obj)->GetComponent(component),
6470 isolate); 6619 isolate);
(...skipping 28 matching lines...) Expand all
6499 } 6648 }
6500 } 6649 }
6501 } 6650 }
6502 return GetHeap()->undefined_value(); 6651 return GetHeap()->undefined_value();
6503 } else { 6652 } else {
6504 return property_dictionary()->SlowReverseLookup(value); 6653 return property_dictionary()->SlowReverseLookup(value);
6505 } 6654 }
6506 } 6655 }
6507 6656
6508 6657
6658 Handle<Map> Map::RawCopy(Handle<Map> map,
6659 int instance_size) {
6660 CALL_HEAP_FUNCTION(map->GetIsolate(),
6661 map->RawCopy(instance_size),
6662 Map);
6663 }
6664
6665
6509 MaybeObject* Map::RawCopy(int instance_size) { 6666 MaybeObject* Map::RawCopy(int instance_size) {
6510 Map* result; 6667 Map* result;
6511 MaybeObject* maybe_result = 6668 MaybeObject* maybe_result =
6512 GetHeap()->AllocateMap(instance_type(), instance_size); 6669 GetHeap()->AllocateMap(instance_type(), instance_size);
6513 if (!maybe_result->To(&result)) return maybe_result; 6670 if (!maybe_result->To(&result)) return maybe_result;
6514 6671
6515 result->set_prototype(prototype()); 6672 result->set_prototype(prototype());
6516 result->set_constructor(constructor()); 6673 result->set_constructor(constructor());
6517 result->set_bit_field(bit_field()); 6674 result->set_bit_field(bit_field());
6518 result->set_bit_field2(bit_field2()); 6675 result->set_bit_field2(bit_field2());
6519 int new_bit_field3 = bit_field3(); 6676 int new_bit_field3 = bit_field3();
6520 new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true); 6677 new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true);
6521 new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0); 6678 new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0);
6522 new_bit_field3 = EnumLengthBits::update(new_bit_field3, kInvalidEnumCache); 6679 new_bit_field3 = EnumLengthBits::update(new_bit_field3, kInvalidEnumCache);
6523 new_bit_field3 = Deprecated::update(new_bit_field3, false); 6680 new_bit_field3 = Deprecated::update(new_bit_field3, false);
6524 new_bit_field3 = IsUnstable::update(new_bit_field3, false); 6681 new_bit_field3 = IsUnstable::update(new_bit_field3, false);
6525 result->set_bit_field3(new_bit_field3); 6682 result->set_bit_field3(new_bit_field3);
6526 return result; 6683 return result;
6527 } 6684 }
6528 6685
6529 6686
6530 Handle<Map> Map::CopyNormalized(Handle<Map> map, 6687 Handle<Map> Map::CopyNormalized(Handle<Map> map,
6531 PropertyNormalizationMode mode, 6688 PropertyNormalizationMode mode,
6532 NormalizedMapSharingMode sharing) { 6689 NormalizedMapSharingMode sharing) {
6533 CALL_HEAP_FUNCTION(map->GetIsolate(), 6690 int new_instance_size = map->instance_size();
6534 map->CopyNormalized(mode, sharing),
6535 Map);
6536 }
6537
6538
6539 MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode,
6540 NormalizedMapSharingMode sharing) {
6541 int new_instance_size = instance_size();
6542 if (mode == CLEAR_INOBJECT_PROPERTIES) { 6691 if (mode == CLEAR_INOBJECT_PROPERTIES) {
6543 new_instance_size -= inobject_properties() * kPointerSize; 6692 new_instance_size -= map->inobject_properties() * kPointerSize;
6544 } 6693 }
6545 6694
6546 Map* result; 6695 Handle<Map> result = Map::RawCopy(map, new_instance_size);
6547 MaybeObject* maybe_result = RawCopy(new_instance_size);
6548 if (!maybe_result->To(&result)) return maybe_result;
6549 6696
6550 if (mode != CLEAR_INOBJECT_PROPERTIES) { 6697 if (mode != CLEAR_INOBJECT_PROPERTIES) {
6551 result->set_inobject_properties(inobject_properties()); 6698 result->set_inobject_properties(map->inobject_properties());
6552 } 6699 }
6553 6700
6554 result->set_is_shared(sharing == SHARED_NORMALIZED_MAP); 6701 result->set_is_shared(sharing == SHARED_NORMALIZED_MAP);
6555 result->set_dictionary_map(true); 6702 result->set_dictionary_map(true);
6556 result->set_migration_target(false); 6703 result->set_migration_target(false);
6557 6704
6558 #ifdef VERIFY_HEAP 6705 #ifdef VERIFY_HEAP
6559 if (FLAG_verify_heap && result->is_shared()) { 6706 if (FLAG_verify_heap && result->is_shared()) {
6560 result->SharedMapVerify(); 6707 result->SharedMapVerify();
6561 } 6708 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
6691 set_transitions(transitions); 6838 set_transitions(transitions);
6692 result->SetBackPointer(this); 6839 result->SetBackPointer(this);
6693 } else { 6840 } else {
6694 descriptors->InitializeRepresentations(Representation::Tagged()); 6841 descriptors->InitializeRepresentations(Representation::Tagged());
6695 } 6842 }
6696 6843
6697 return result; 6844 return result;
6698 } 6845 }
6699 6846
6700 6847
6701 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map,
6702 int new_descriptor,
6703 Handle<DescriptorArray> descriptors) {
6704 CALL_HEAP_FUNCTION(map->GetIsolate(),
6705 map->CopyInstallDescriptors(new_descriptor, *descriptors),
6706 Map);
6707 }
6708
6709
6710 // Since this method is used to rewrite an existing transition tree, it can 6848 // Since this method is used to rewrite an existing transition tree, it can
6711 // always insert transitions without checking. 6849 // always insert transitions without checking.
6712 MaybeObject* Map::CopyInstallDescriptors(int new_descriptor, 6850 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map,
6713 DescriptorArray* descriptors) { 6851 int new_descriptor,
6852 Handle<DescriptorArray> descriptors) {
6714 ASSERT(descriptors->IsSortedNoDuplicates()); 6853 ASSERT(descriptors->IsSortedNoDuplicates());
6715 6854
6716 Map* result; 6855 Handle<Map> result = Map::CopyDropDescriptors(map);
6717 MaybeObject* maybe_result = CopyDropDescriptors();
6718 if (!maybe_result->To(&result)) return maybe_result;
6719 6856
6720 result->InitializeDescriptors(descriptors); 6857 result->InitializeDescriptors(*descriptors);
6721 result->SetNumberOfOwnDescriptors(new_descriptor + 1); 6858 result->SetNumberOfOwnDescriptors(new_descriptor + 1);
6722 6859
6723 int unused_property_fields = this->unused_property_fields(); 6860 int unused_property_fields = map->unused_property_fields();
6724 if (descriptors->GetDetails(new_descriptor).type() == FIELD) { 6861 if (descriptors->GetDetails(new_descriptor).type() == FIELD) {
6725 unused_property_fields = this->unused_property_fields() - 1; 6862 unused_property_fields = map->unused_property_fields() - 1;
6726 if (unused_property_fields < 0) { 6863 if (unused_property_fields < 0) {
6727 unused_property_fields += JSObject::kFieldsAdded; 6864 unused_property_fields += JSObject::kFieldsAdded;
6728 } 6865 }
6729 } 6866 }
6730 6867
6731 result->set_unused_property_fields(unused_property_fields); 6868 result->set_unused_property_fields(unused_property_fields);
6732 result->set_owns_descriptors(false); 6869 result->set_owns_descriptors(false);
6733 6870
6734 Name* name = descriptors->GetKey(new_descriptor); 6871 Handle<Name> name = handle(descriptors->GetKey(new_descriptor));
6735 TransitionArray* transitions; 6872 Handle<TransitionArray> transitions = Map::AddTransition(map, name, result,
6736 MaybeObject* maybe_transitions = 6873 SIMPLE_TRANSITION);
6737 AddTransition(name, result, SIMPLE_TRANSITION);
6738 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
6739 6874
6740 set_transitions(transitions); 6875 map->set_transitions(*transitions);
6741 result->SetBackPointer(this); 6876 result->SetBackPointer(*map);
6742 6877
6743 return result; 6878 return result;
6744 } 6879 }
6745 6880
6746 6881
6747 MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) { 6882 MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) {
6748 if (flag == INSERT_TRANSITION) { 6883 if (flag == INSERT_TRANSITION) {
6749 ASSERT(!HasElementsTransition() || 6884 ASSERT(!HasElementsTransition() ||
6750 ((elements_transition_map()->elements_kind() == DICTIONARY_ELEMENTS || 6885 ((elements_transition_map()->elements_kind() == DICTIONARY_ELEMENTS ||
6751 IsExternalArrayElementsKind( 6886 IsExternalArrayElementsKind(
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
6789 if (insert_transition) { 6924 if (insert_transition) {
6790 MaybeObject* added_elements = set_elements_transition_map(new_map); 6925 MaybeObject* added_elements = set_elements_transition_map(new_map);
6791 if (added_elements->IsFailure()) return added_elements; 6926 if (added_elements->IsFailure()) return added_elements;
6792 new_map->SetBackPointer(this); 6927 new_map->SetBackPointer(this);
6793 } 6928 }
6794 6929
6795 return new_map; 6930 return new_map;
6796 } 6931 }
6797 6932
6798 6933
6799 MaybeObject* Map::CopyForObserved() { 6934 Handle<Map> Map::CopyForObserved(Handle<Map> map) {
6800 ASSERT(!is_observed()); 6935 ASSERT(!map->is_observed());
6936
6937 Isolate* isolate = map->GetIsolate();
6801 6938
6802 // In case the map owned its own descriptors, share the descriptors and 6939 // In case the map owned its own descriptors, share the descriptors and
6803 // transfer ownership to the new map. 6940 // transfer ownership to the new map.
6804 Map* new_map; 6941 Handle<Map> new_map;
6805 MaybeObject* maybe_new_map; 6942 if (map->owns_descriptors()) {
6806 if (owns_descriptors()) { 6943 new_map = Map::CopyDropDescriptors(map);
6807 maybe_new_map = CopyDropDescriptors();
6808 } else { 6944 } else {
6809 maybe_new_map = Copy(); 6945 new_map = Map::Copy(map);
6810 } 6946 }
6811 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
6812 6947
6813 TransitionArray* transitions; 6948 Handle<TransitionArray> transitions =
6814 MaybeObject* maybe_transitions = AddTransition(GetHeap()->observed_symbol(), 6949 Map::AddTransition(map, isolate->factory()->observed_symbol(), new_map,
6815 new_map, 6950 FULL_TRANSITION);
6816 FULL_TRANSITION); 6951
6817 if (!maybe_transitions->To(&transitions)) return maybe_transitions; 6952 map->set_transitions(*transitions);
6818 set_transitions(transitions);
6819 6953
6820 new_map->set_is_observed(true); 6954 new_map->set_is_observed(true);
6821 6955
6822 if (owns_descriptors()) { 6956 if (map->owns_descriptors()) {
6823 new_map->InitializeDescriptors(instance_descriptors()); 6957 new_map->InitializeDescriptors(map->instance_descriptors());
6824 set_owns_descriptors(false); 6958 map->set_owns_descriptors(false);
6825 } 6959 }
6826 6960
6827 new_map->SetBackPointer(this); 6961 new_map->SetBackPointer(*map);
6828 return new_map; 6962 return new_map;
6829 } 6963 }
6830 6964
6831 6965
6832 MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() { 6966 MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() {
6833 if (pre_allocated_property_fields() == 0) return CopyDropDescriptors(); 6967 if (pre_allocated_property_fields() == 0) return CopyDropDescriptors();
6834 6968
6835 // If the map has pre-allocated properties always start out with a descriptor 6969 // If the map has pre-allocated properties always start out with a descriptor
6836 // array describing these properties. 6970 // array describing these properties.
6837 ASSERT(constructor()->IsJSFunction()); 6971 ASSERT(constructor()->IsJSFunction());
(...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after
7695 return cache; 7829 return cache;
7696 } 7830 }
7697 7831
7698 7832
7699 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { 7833 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) {
7700 ElementsAccessor* accessor = array->GetElementsAccessor(); 7834 ElementsAccessor* accessor = array->GetElementsAccessor();
7701 MaybeObject* maybe_result = 7835 MaybeObject* maybe_result =
7702 accessor->AddElementsToFixedArray(array, array, this); 7836 accessor->AddElementsToFixedArray(array, array, this);
7703 FixedArray* result; 7837 FixedArray* result;
7704 if (!maybe_result->To<FixedArray>(&result)) return maybe_result; 7838 if (!maybe_result->To<FixedArray>(&result)) return maybe_result;
7705 #ifdef DEBUG 7839 #ifdef ENABLE_SLOW_ASSERTS
7706 if (FLAG_enable_slow_asserts) { 7840 if (FLAG_enable_slow_asserts) {
7707 for (int i = 0; i < result->length(); i++) { 7841 for (int i = 0; i < result->length(); i++) {
7708 Object* current = result->get(i); 7842 Object* current = result->get(i);
7709 ASSERT(current->IsNumber() || current->IsName()); 7843 ASSERT(current->IsNumber() || current->IsName());
7710 } 7844 }
7711 } 7845 }
7712 #endif 7846 #endif
7713 return result; 7847 return result;
7714 } 7848 }
7715 7849
7716 7850
7717 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) { 7851 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) {
7718 ElementsAccessor* accessor = ElementsAccessor::ForArray(other); 7852 ElementsAccessor* accessor = ElementsAccessor::ForArray(other);
7719 MaybeObject* maybe_result = 7853 MaybeObject* maybe_result =
7720 accessor->AddElementsToFixedArray(NULL, NULL, this, other); 7854 accessor->AddElementsToFixedArray(NULL, NULL, this, other);
7721 FixedArray* result; 7855 FixedArray* result;
7722 if (!maybe_result->To(&result)) return maybe_result; 7856 if (!maybe_result->To(&result)) return maybe_result;
7723 #ifdef DEBUG 7857 #ifdef ENABLE_SLOW_ASSERTS
7724 if (FLAG_enable_slow_asserts) { 7858 if (FLAG_enable_slow_asserts) {
7725 for (int i = 0; i < result->length(); i++) { 7859 for (int i = 0; i < result->length(); i++) {
7726 Object* current = result->get(i); 7860 Object* current = result->get(i);
7727 ASSERT(current->IsNumber() || current->IsName()); 7861 ASSERT(current->IsNumber() || current->IsName());
7728 } 7862 }
7729 } 7863 }
7730 #endif 7864 #endif
7731 return result; 7865 return result;
7732 } 7866 }
7733 7867
(...skipping 1034 matching lines...) Expand 10 before | Expand all | Expand 10 after
8768 8902
8769 bool String::SlowEquals(String* other) { 8903 bool String::SlowEquals(String* other) {
8770 // Fast check: negative check with lengths. 8904 // Fast check: negative check with lengths.
8771 int len = length(); 8905 int len = length();
8772 if (len != other->length()) return false; 8906 if (len != other->length()) return false;
8773 if (len == 0) return true; 8907 if (len == 0) return true;
8774 8908
8775 // Fast check: if hash code is computed for both strings 8909 // Fast check: if hash code is computed for both strings
8776 // a fast negative check can be performed. 8910 // a fast negative check can be performed.
8777 if (HasHashCode() && other->HasHashCode()) { 8911 if (HasHashCode() && other->HasHashCode()) {
8778 #ifdef DEBUG 8912 #ifdef ENABLE_SLOW_ASSERTS
8779 if (FLAG_enable_slow_asserts) { 8913 if (FLAG_enable_slow_asserts) {
8780 if (Hash() != other->Hash()) { 8914 if (Hash() != other->Hash()) {
8781 bool found_difference = false; 8915 bool found_difference = false;
8782 for (int i = 0; i < len; i++) { 8916 for (int i = 0; i < len; i++) {
8783 if (Get(i) != other->Get(i)) { 8917 if (Get(i) != other->Get(i)) {
8784 found_difference = true; 8918 found_difference = true;
8785 break; 8919 break;
8786 } 8920 }
8787 } 8921 }
8788 ASSERT(found_difference); 8922 ASSERT(found_difference);
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
9023 9157
9024 Address start_of_string = string->address(); 9158 Address start_of_string = string->address();
9025 ASSERT_OBJECT_ALIGNED(start_of_string); 9159 ASSERT_OBJECT_ALIGNED(start_of_string);
9026 ASSERT_OBJECT_ALIGNED(start_of_string + new_size); 9160 ASSERT_OBJECT_ALIGNED(start_of_string + new_size);
9027 9161
9028 Heap* heap = string->GetHeap(); 9162 Heap* heap = string->GetHeap();
9029 NewSpace* newspace = heap->new_space(); 9163 NewSpace* newspace = heap->new_space();
9030 if (newspace->Contains(start_of_string) && 9164 if (newspace->Contains(start_of_string) &&
9031 newspace->top() == start_of_string + old_size) { 9165 newspace->top() == start_of_string + old_size) {
9032 // Last allocated object in new space. Simply lower allocation top. 9166 // Last allocated object in new space. Simply lower allocation top.
9033 *(newspace->allocation_top_address()) = start_of_string + new_size; 9167 newspace->set_top(start_of_string + new_size);
9034 } else { 9168 } else {
9035 // Sizes are pointer size aligned, so that we can use filler objects 9169 // Sizes are pointer size aligned, so that we can use filler objects
9036 // that are a multiple of pointer size. 9170 // that are a multiple of pointer size.
9037 heap->CreateFillerObjectAt(start_of_string + new_size, delta); 9171 heap->CreateFillerObjectAt(start_of_string + new_size, delta);
9038 } 9172 }
9039 if (Marking::IsBlack(Marking::MarkBitFrom(start_of_string))) { 9173 if (Marking::IsBlack(Marking::MarkBitFrom(start_of_string))) {
9040 MemoryChunk::IncrementLiveBytesFromMutator(start_of_string, -delta); 9174 MemoryChunk::IncrementLiveBytesFromMutator(start_of_string, -delta);
9041 } 9175 }
9042 9176
9043 9177
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
9259 // TODO(verwaest) Should be an assert, otherwise back pointers are not 9393 // TODO(verwaest) Should be an assert, otherwise back pointers are not
9260 // properly cleared. 9394 // properly cleared.
9261 if (transition_index == t->number_of_transitions()) return; 9395 if (transition_index == t->number_of_transitions()) return;
9262 9396
9263 int number_of_own_descriptors = NumberOfOwnDescriptors(); 9397 int number_of_own_descriptors = NumberOfOwnDescriptors();
9264 9398
9265 if (descriptors_owner_died) { 9399 if (descriptors_owner_died) {
9266 if (number_of_own_descriptors > 0) { 9400 if (number_of_own_descriptors > 0) {
9267 TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors); 9401 TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors);
9268 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors); 9402 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors);
9403 set_owns_descriptors(true);
9269 } else { 9404 } else {
9270 ASSERT(descriptors == GetHeap()->empty_descriptor_array()); 9405 ASSERT(descriptors == GetHeap()->empty_descriptor_array());
9271 } 9406 }
9272 } 9407 }
9273 9408
9274 int trim = t->number_of_transitions() - transition_index; 9409 int trim = t->number_of_transitions() - transition_index;
9275 if (trim > 0) { 9410 if (trim > 0) {
9276 RightTrimFixedArray<FROM_GC>(heap, t, t->IsSimpleTransition() 9411 RightTrimFixedArray<FROM_GC>(heap, t, t->IsSimpleTransition()
9277 ? trim : trim * TransitionArray::kTransitionSize); 9412 ? trim : trim * TransitionArray::kTransitionSize);
9278 } 9413 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
9315 9450
9316 9451
9317 bool Map::EquivalentToForNormalization(Map* other, 9452 bool Map::EquivalentToForNormalization(Map* other,
9318 PropertyNormalizationMode mode) { 9453 PropertyNormalizationMode mode) {
9319 int properties = mode == CLEAR_INOBJECT_PROPERTIES 9454 int properties = mode == CLEAR_INOBJECT_PROPERTIES
9320 ? 0 : other->inobject_properties(); 9455 ? 0 : other->inobject_properties();
9321 return CheckEquivalent(this, other) && inobject_properties() == properties; 9456 return CheckEquivalent(this, other) && inobject_properties() == properties;
9322 } 9457 }
9323 9458
9324 9459
9460 void ConstantPoolArray::ConstantPoolIterateBody(ObjectVisitor* v) {
9461 int first_ptr_offset = OffsetOfElementAt(first_ptr_index());
9462 int last_ptr_offset =
9463 OffsetOfElementAt(first_ptr_index() + count_of_ptr_entries());
9464 v->VisitPointers(
9465 HeapObject::RawField(this, first_ptr_offset),
9466 HeapObject::RawField(this, last_ptr_offset));
9467 }
9468
9469
9325 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) { 9470 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) {
9326 // Iterate over all fields in the body but take care in dealing with 9471 // Iterate over all fields in the body but take care in dealing with
9327 // the code entry. 9472 // the code entry.
9328 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset); 9473 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset);
9329 v->VisitCodeEntry(this->address() + kCodeEntryOffset); 9474 v->VisitCodeEntry(this->address() + kCodeEntryOffset);
9330 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size); 9475 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size);
9331 } 9476 }
9332 9477
9333 9478
9334 void JSFunction::MarkForLazyRecompilation() { 9479 void JSFunction::MarkForLazyRecompilation() {
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
9760 // "-" all but the top-level function 9905 // "-" all but the top-level function
9761 // "-name" all but the function "name" 9906 // "-name" all but the function "name"
9762 // "" only the top-level function 9907 // "" only the top-level function
9763 // "name" only the function "name" 9908 // "name" only the function "name"
9764 // "name*" only functions starting with "name" 9909 // "name*" only functions starting with "name"
9765 bool JSFunction::PassesFilter(const char* raw_filter) { 9910 bool JSFunction::PassesFilter(const char* raw_filter) {
9766 if (*raw_filter == '*') return true; 9911 if (*raw_filter == '*') return true;
9767 String* name = shared()->DebugName(); 9912 String* name = shared()->DebugName();
9768 Vector<const char> filter = CStrVector(raw_filter); 9913 Vector<const char> filter = CStrVector(raw_filter);
9769 if (filter.length() == 0) return name->length() == 0; 9914 if (filter.length() == 0) return name->length() == 0;
9770 if (filter[0] != '-' && name->IsUtf8EqualTo(filter)) return true; 9915 if (filter[0] == '-') {
9771 if (filter[0] == '-' && 9916 if (filter.length() == 1) {
9772 !name->IsUtf8EqualTo(filter.SubVector(1, filter.length()))) { 9917 return (name->length() != 0);
9918 } else if (!name->IsUtf8EqualTo(filter.SubVector(1, filter.length()))) {
9919 return true;
9920 }
9921 } else if (name->IsUtf8EqualTo(filter)) {
9773 return true; 9922 return true;
9774 } 9923 }
9775 if (filter[filter.length() - 1] == '*' && 9924 if (filter[filter.length() - 1] == '*' &&
9776 name->IsUtf8EqualTo(filter.SubVector(0, filter.length() - 1), true)) { 9925 name->IsUtf8EqualTo(filter.SubVector(0, filter.length() - 1), true)) {
9777 return true; 9926 return true;
9778 } 9927 }
9779 return false; 9928 return false;
9780 } 9929 }
9781 9930
9782 9931
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
10167 10316
10168 10317
10169 void ObjectVisitor::VisitEmbeddedPointer(RelocInfo* rinfo) { 10318 void ObjectVisitor::VisitEmbeddedPointer(RelocInfo* rinfo) {
10170 ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); 10319 ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
10171 VisitPointer(rinfo->target_object_address()); 10320 VisitPointer(rinfo->target_object_address());
10172 } 10321 }
10173 10322
10174 10323
10175 void ObjectVisitor::VisitExternalReference(RelocInfo* rinfo) { 10324 void ObjectVisitor::VisitExternalReference(RelocInfo* rinfo) {
10176 Address* p = rinfo->target_reference_address(); 10325 Address* p = rinfo->target_reference_address();
10177 VisitExternalReferences(p, p + 1); 10326 VisitExternalReference(p);
10178 } 10327 }
10179 10328
10180 10329
10181 void Code::InvalidateRelocation() { 10330 void Code::InvalidateRelocation() {
10182 set_relocation_info(GetHeap()->empty_byte_array()); 10331 set_relocation_info(GetHeap()->empty_byte_array());
10183 } 10332 }
10184 10333
10185 10334
10186 void Code::Relocate(intptr_t delta) { 10335 void Code::Relocate(intptr_t delta) {
10187 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { 10336 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
10224 } else if (RelocInfo::IsCodeTarget(mode)) { 10373 } else if (RelocInfo::IsCodeTarget(mode)) {
10225 // rewrite code handles in inline cache targets to direct 10374 // rewrite code handles in inline cache targets to direct
10226 // pointers to the first instruction in the code object 10375 // pointers to the first instruction in the code object
10227 Handle<Object> p = it.rinfo()->target_object_handle(origin); 10376 Handle<Object> p = it.rinfo()->target_object_handle(origin);
10228 Code* code = Code::cast(*p); 10377 Code* code = Code::cast(*p);
10229 it.rinfo()->set_target_address(code->instruction_start(), 10378 it.rinfo()->set_target_address(code->instruction_start(),
10230 SKIP_WRITE_BARRIER); 10379 SKIP_WRITE_BARRIER);
10231 } else if (RelocInfo::IsRuntimeEntry(mode)) { 10380 } else if (RelocInfo::IsRuntimeEntry(mode)) {
10232 Address p = it.rinfo()->target_runtime_entry(origin); 10381 Address p = it.rinfo()->target_runtime_entry(origin);
10233 it.rinfo()->set_target_runtime_entry(p, SKIP_WRITE_BARRIER); 10382 it.rinfo()->set_target_runtime_entry(p, SKIP_WRITE_BARRIER);
10383 } else if (mode == RelocInfo::CODE_AGE_SEQUENCE) {
10384 Handle<Object> p = it.rinfo()->code_age_stub_handle(origin);
10385 Code* code = Code::cast(*p);
10386 it.rinfo()->set_code_age_stub(code);
10234 } else { 10387 } else {
10235 it.rinfo()->apply(delta); 10388 it.rinfo()->apply(delta);
10236 } 10389 }
10237 } 10390 }
10238 CPU::FlushICache(instruction_start(), instruction_size()); 10391 CPU::FlushICache(instruction_start(), instruction_size());
10239 } 10392 }
10240 10393
10241 10394
10242 // Locate the source position which is closest to the address in the code. This 10395 // Locate the source position which is closest to the address in the code. This
10243 // is using the source position information embedded in the relocation info. 10396 // is using the source position information embedded in the relocation info.
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
10461 ASSERT(kind() == FUNCTION); 10614 ASSERT(kind() == FUNCTION);
10462 BackEdgeTable back_edges(this, &no_gc); 10615 BackEdgeTable back_edges(this, &no_gc);
10463 for (uint32_t i = 0; i < back_edges.length(); i++) { 10616 for (uint32_t i = 0; i < back_edges.length(); i++) {
10464 if (back_edges.pc_offset(i) == pc_offset) return back_edges.ast_id(i); 10617 if (back_edges.pc_offset(i) == pc_offset) return back_edges.ast_id(i);
10465 } 10618 }
10466 return BailoutId::None(); 10619 return BailoutId::None();
10467 } 10620 }
10468 10621
10469 10622
10470 void Code::MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate) { 10623 void Code::MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate) {
10471 PatchPlatformCodeAge(isolate, sequence, kNoAge, NO_MARKING_PARITY); 10624 PatchPlatformCodeAge(isolate, sequence, kNoAgeCodeAge, NO_MARKING_PARITY);
10472 } 10625 }
10473 10626
10474 10627
10628 void Code::MarkCodeAsExecuted(byte* sequence, Isolate* isolate) {
10629 PatchPlatformCodeAge(isolate, sequence, kExecutedOnceCodeAge,
10630 NO_MARKING_PARITY);
10631 }
10632
10633
10475 void Code::MakeOlder(MarkingParity current_parity) { 10634 void Code::MakeOlder(MarkingParity current_parity) {
10476 byte* sequence = FindCodeAgeSequence(); 10635 byte* sequence = FindCodeAgeSequence();
10477 if (sequence != NULL) { 10636 if (sequence != NULL) {
10478 Age age; 10637 Age age;
10479 MarkingParity code_parity; 10638 MarkingParity code_parity;
10480 GetCodeAgeAndParity(sequence, &age, &code_parity); 10639 GetCodeAgeAndParity(sequence, &age, &code_parity);
10481 if (age != kLastCodeAge && code_parity != current_parity) { 10640 if (age != kLastCodeAge && code_parity != current_parity) {
10482 PatchPlatformCodeAge(GetIsolate(), 10641 PatchPlatformCodeAge(GetIsolate(),
10483 sequence, 10642 sequence,
10484 static_cast<Age>(age + 1), 10643 static_cast<Age>(age + 1),
10485 current_parity); 10644 current_parity);
10486 } 10645 }
10487 } 10646 }
10488 } 10647 }
10489 10648
10490 10649
10491 bool Code::IsOld() { 10650 bool Code::IsOld() {
10492 byte* sequence = FindCodeAgeSequence(); 10651 Age age = GetAge();
10493 if (sequence == NULL) return false; 10652 return age >= kIsOldCodeAge;
10494 Age age;
10495 MarkingParity parity;
10496 GetCodeAgeAndParity(sequence, &age, &parity);
10497 return age >= kSexagenarianCodeAge;
10498 } 10653 }
10499 10654
10500 10655
10501 byte* Code::FindCodeAgeSequence() { 10656 byte* Code::FindCodeAgeSequence() {
10502 return FLAG_age_code && 10657 return FLAG_age_code &&
10503 prologue_offset() != kPrologueOffsetNotSet && 10658 prologue_offset() != Code::kPrologueOffsetNotSet &&
10504 (kind() == OPTIMIZED_FUNCTION || 10659 (kind() == OPTIMIZED_FUNCTION ||
10505 (kind() == FUNCTION && !has_debug_break_slots())) 10660 (kind() == FUNCTION && !has_debug_break_slots()))
10506 ? instruction_start() + prologue_offset() 10661 ? instruction_start() + prologue_offset()
10507 : NULL; 10662 : NULL;
10508 } 10663 }
10509 10664
10510 10665
10511 int Code::GetAge() { 10666 Code::Age Code::GetAge() {
10512 byte* sequence = FindCodeAgeSequence(); 10667 byte* sequence = FindCodeAgeSequence();
10513 if (sequence == NULL) { 10668 if (sequence == NULL) {
10514 return Code::kNoAge; 10669 return Code::kNoAgeCodeAge;
10515 } 10670 }
10516 Age age; 10671 Age age;
10517 MarkingParity parity; 10672 MarkingParity parity;
10518 GetCodeAgeAndParity(sequence, &age, &parity); 10673 GetCodeAgeAndParity(sequence, &age, &parity);
10519 return age; 10674 return age;
10520 } 10675 }
10521 10676
10522 10677
10523 void Code::GetCodeAgeAndParity(Code* code, Age* age, 10678 void Code::GetCodeAgeAndParity(Code* code, Age* age,
10524 MarkingParity* parity) { 10679 MarkingParity* parity) {
10525 Isolate* isolate = code->GetIsolate(); 10680 Isolate* isolate = code->GetIsolate();
10526 Builtins* builtins = isolate->builtins(); 10681 Builtins* builtins = isolate->builtins();
10527 Code* stub = NULL; 10682 Code* stub = NULL;
10528 #define HANDLE_CODE_AGE(AGE) \ 10683 #define HANDLE_CODE_AGE(AGE) \
10529 stub = *builtins->Make##AGE##CodeYoungAgainEvenMarking(); \ 10684 stub = *builtins->Make##AGE##CodeYoungAgainEvenMarking(); \
10530 if (code == stub) { \ 10685 if (code == stub) { \
10531 *age = k##AGE##CodeAge; \ 10686 *age = k##AGE##CodeAge; \
10532 *parity = EVEN_MARKING_PARITY; \ 10687 *parity = EVEN_MARKING_PARITY; \
10533 return; \ 10688 return; \
10534 } \ 10689 } \
10535 stub = *builtins->Make##AGE##CodeYoungAgainOddMarking(); \ 10690 stub = *builtins->Make##AGE##CodeYoungAgainOddMarking(); \
10536 if (code == stub) { \ 10691 if (code == stub) { \
10537 *age = k##AGE##CodeAge; \ 10692 *age = k##AGE##CodeAge; \
10538 *parity = ODD_MARKING_PARITY; \ 10693 *parity = ODD_MARKING_PARITY; \
10539 return; \ 10694 return; \
10540 } 10695 }
10541 CODE_AGE_LIST(HANDLE_CODE_AGE) 10696 CODE_AGE_LIST(HANDLE_CODE_AGE)
10542 #undef HANDLE_CODE_AGE 10697 #undef HANDLE_CODE_AGE
10698 stub = *builtins->MarkCodeAsExecutedOnce();
10699 if (code == stub) {
10700 // Treat that's never been executed as old immediatly.
10701 *age = kIsOldCodeAge;
10702 *parity = NO_MARKING_PARITY;
10703 return;
10704 }
10705 stub = *builtins->MarkCodeAsExecutedTwice();
10706 if (code == stub) {
10707 // Pre-age code that has only been executed once.
10708 *age = kPreAgedCodeAge;
10709 *parity = NO_MARKING_PARITY;
10710 return;
10711 }
10543 UNREACHABLE(); 10712 UNREACHABLE();
10544 } 10713 }
10545 10714
10546 10715
10547 Code* Code::GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity) { 10716 Code* Code::GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity) {
10548 Builtins* builtins = isolate->builtins(); 10717 Builtins* builtins = isolate->builtins();
10549 switch (age) { 10718 switch (age) {
10550 #define HANDLE_CODE_AGE(AGE) \ 10719 #define HANDLE_CODE_AGE(AGE) \
10551 case k##AGE##CodeAge: { \ 10720 case k##AGE##CodeAge: { \
10552 Code* stub = parity == EVEN_MARKING_PARITY \ 10721 Code* stub = parity == EVEN_MARKING_PARITY \
10553 ? *builtins->Make##AGE##CodeYoungAgainEvenMarking() \ 10722 ? *builtins->Make##AGE##CodeYoungAgainEvenMarking() \
10554 : *builtins->Make##AGE##CodeYoungAgainOddMarking(); \ 10723 : *builtins->Make##AGE##CodeYoungAgainOddMarking(); \
10555 return stub; \ 10724 return stub; \
10556 } 10725 }
10557 CODE_AGE_LIST(HANDLE_CODE_AGE) 10726 CODE_AGE_LIST(HANDLE_CODE_AGE)
10558 #undef HANDLE_CODE_AGE 10727 #undef HANDLE_CODE_AGE
10728 case kNotExecutedCodeAge: {
10729 ASSERT(parity == NO_MARKING_PARITY);
10730 return *builtins->MarkCodeAsExecutedOnce();
10731 }
10732 case kExecutedOnceCodeAge: {
10733 ASSERT(parity == NO_MARKING_PARITY);
10734 return *builtins->MarkCodeAsExecutedTwice();
10735 }
10559 default: 10736 default:
10560 UNREACHABLE(); 10737 UNREACHABLE();
10561 break; 10738 break;
10562 } 10739 }
10563 return NULL; 10740 return NULL;
10564 } 10741 }
10565 10742
10566 10743
10567 void Code::PrintDeoptLocation(int bailout_id) { 10744 void Code::PrintDeoptLocation(int bailout_id) {
10568 const char* last_comment = NULL; 10745 const char* last_comment = NULL;
(...skipping 1944 matching lines...) Expand 10 before | Expand all | Expand 10 after
12513 } 12690 }
12514 12691
12515 12692
12516 void JSObject::TransitionElementsKind(Handle<JSObject> object, 12693 void JSObject::TransitionElementsKind(Handle<JSObject> object,
12517 ElementsKind to_kind) { 12694 ElementsKind to_kind) {
12518 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), 12695 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(),
12519 object->TransitionElementsKind(to_kind)); 12696 object->TransitionElementsKind(to_kind));
12520 } 12697 }
12521 12698
12522 12699
12700 bool AllocationSite::IsNestedSite() {
12701 ASSERT(FLAG_trace_track_allocation_sites);
12702 Object* current = GetHeap()->allocation_sites_list();
12703 while (current != NULL && current->IsAllocationSite()) {
12704 AllocationSite* current_site = AllocationSite::cast(current);
12705 if (current_site->nested_site() == this) {
12706 return true;
12707 }
12708 current = current_site->weak_next();
12709 }
12710 return false;
12711 }
12712
12713
12523 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) { 12714 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) {
12524 if (!FLAG_track_allocation_sites || !IsJSArray()) { 12715 if (!FLAG_track_allocation_sites || !IsJSArray()) {
12525 return this; 12716 return this;
12526 } 12717 }
12527 12718
12528 AllocationMemento* memento = AllocationMemento::FindForJSObject(this); 12719 AllocationMemento* memento = AllocationMemento::FindForJSObject(this);
12529 if (memento == NULL || !memento->IsValid()) { 12720 if (memento == NULL || !memento->IsValid()) {
12530 return this; 12721 return this;
12531 } 12722 }
12532 12723
12533 // Walk through to the Allocation Site 12724 // Walk through to the Allocation Site
12534 AllocationSite* site = memento->GetAllocationSite(); 12725 AllocationSite* site = memento->GetAllocationSite();
12535 if (site->IsLiteralSite()) { 12726 if (site->SitePointsToLiteral() &&
12727 site->transition_info()->IsJSArray()) {
12536 JSArray* transition_info = JSArray::cast(site->transition_info()); 12728 JSArray* transition_info = JSArray::cast(site->transition_info());
12537 ElementsKind kind = transition_info->GetElementsKind(); 12729 ElementsKind kind = transition_info->GetElementsKind();
12538 // if kind is holey ensure that to_kind is as well. 12730 // if kind is holey ensure that to_kind is as well.
12539 if (IsHoleyElementsKind(kind)) { 12731 if (IsHoleyElementsKind(kind)) {
12540 to_kind = GetHoleyElementsKind(to_kind); 12732 to_kind = GetHoleyElementsKind(to_kind);
12541 } 12733 }
12542 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { 12734 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
12543 // If the array is huge, it's not likely to be defined in a local 12735 // If the array is huge, it's not likely to be defined in a local
12544 // function, so we shouldn't make new instances of it very often. 12736 // function, so we shouldn't make new instances of it very often.
12545 uint32_t length = 0; 12737 uint32_t length = 0;
12546 CHECK(transition_info->length()->ToArrayIndex(&length)); 12738 CHECK(transition_info->length()->ToArrayIndex(&length));
12547 if (length <= AllocationSite::kMaximumArrayBytesToPretransition) { 12739 if (length <= AllocationSite::kMaximumArrayBytesToPretransition) {
12548 if (FLAG_trace_track_allocation_sites) { 12740 if (FLAG_trace_track_allocation_sites) {
12741 bool is_nested = site->IsNestedSite();
12549 PrintF( 12742 PrintF(
12550 "AllocationSite: JSArray %p boilerplate updated %s->%s\n", 12743 "AllocationSite: JSArray %p boilerplate %s updated %s->%s\n",
12551 reinterpret_cast<void*>(this), 12744 reinterpret_cast<void*>(this),
12745 is_nested ? "(nested)" : "",
12552 ElementsKindToString(kind), 12746 ElementsKindToString(kind),
12553 ElementsKindToString(to_kind)); 12747 ElementsKindToString(to_kind));
12554 } 12748 }
12555 return transition_info->TransitionElementsKind(to_kind); 12749 return transition_info->TransitionElementsKind(to_kind);
12556 } 12750 }
12557 } 12751 }
12558 } else { 12752 } else {
12559 ElementsKind kind = site->GetElementsKind(); 12753 ElementsKind kind = site->GetElementsKind();
12560 // if kind is holey ensure that to_kind is as well. 12754 // if kind is holey ensure that to_kind is as well.
12561 if (IsHoleyElementsKind(kind)) { 12755 if (IsHoleyElementsKind(kind)) {
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
12944 InterceptorInfo* JSObject::GetIndexedInterceptor() { 13138 InterceptorInfo* JSObject::GetIndexedInterceptor() {
12945 ASSERT(map()->has_indexed_interceptor()); 13139 ASSERT(map()->has_indexed_interceptor());
12946 JSFunction* constructor = JSFunction::cast(map()->constructor()); 13140 JSFunction* constructor = JSFunction::cast(map()->constructor());
12947 ASSERT(constructor->shared()->IsApiFunction()); 13141 ASSERT(constructor->shared()->IsApiFunction());
12948 Object* result = 13142 Object* result =
12949 constructor->shared()->get_api_func_data()->indexed_property_handler(); 13143 constructor->shared()->get_api_func_data()->indexed_property_handler();
12950 return InterceptorInfo::cast(result); 13144 return InterceptorInfo::cast(result);
12951 } 13145 }
12952 13146
12953 13147
12954 MaybeObject* JSObject::GetPropertyPostInterceptor( 13148 Handle<Object> JSObject::GetPropertyPostInterceptor(
12955 Object* receiver, 13149 Handle<JSObject> object,
12956 Name* name, 13150 Handle<Object> receiver,
13151 Handle<Name> name,
12957 PropertyAttributes* attributes) { 13152 PropertyAttributes* attributes) {
12958 // Check local property in holder, ignore interceptor. 13153 // Check local property in holder, ignore interceptor.
12959 LookupResult result(GetIsolate()); 13154 Isolate* isolate = object->GetIsolate();
12960 LocalLookupRealNamedProperty(name, &result); 13155 LookupResult lookup(isolate);
12961 if (result.IsFound()) { 13156 object->LocalLookupRealNamedProperty(*name, &lookup);
12962 return GetProperty(receiver, &result, name, attributes); 13157 Handle<Object> result;
13158 if (lookup.IsFound()) {
13159 result = GetProperty(object, receiver, &lookup, name, attributes);
13160 } else {
13161 // Continue searching via the prototype chain.
13162 Handle<Object> prototype(object->GetPrototype(), isolate);
13163 *attributes = ABSENT;
13164 if (prototype->IsNull()) return isolate->factory()->undefined_value();
13165 result = GetPropertyWithReceiver(prototype, receiver, name, attributes);
12963 } 13166 }
12964 // Continue searching via the prototype chain. 13167 return result;
12965 Object* pt = GetPrototype();
12966 *attributes = ABSENT;
12967 if (pt->IsNull()) return GetHeap()->undefined_value();
12968 return pt->GetPropertyWithReceiver(receiver, name, attributes);
12969 } 13168 }
12970 13169
12971 13170
12972 MaybeObject* JSObject::GetLocalPropertyPostInterceptor( 13171 MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
12973 Object* receiver, 13172 Object* receiver,
12974 Name* name, 13173 Name* name,
12975 PropertyAttributes* attributes) { 13174 PropertyAttributes* attributes) {
12976 // Check local property in holder, ignore interceptor. 13175 // Check local property in holder, ignore interceptor.
12977 LookupResult result(GetIsolate()); 13176 LookupResult result(GetIsolate());
12978 LocalLookupRealNamedProperty(name, &result); 13177 LocalLookupRealNamedProperty(name, &result);
12979 if (result.IsFound()) { 13178 if (result.IsFound()) {
12980 return GetProperty(receiver, &result, name, attributes); 13179 return GetProperty(receiver, &result, name, attributes);
12981 } 13180 }
12982 return GetHeap()->undefined_value(); 13181 return GetHeap()->undefined_value();
12983 } 13182 }
12984 13183
12985 13184
12986 MaybeObject* JSObject::GetPropertyWithInterceptor( 13185 Handle<Object> JSObject::GetPropertyWithInterceptor(
12987 Object* receiver, 13186 Handle<JSObject> object,
12988 Name* name, 13187 Handle<Object> receiver,
13188 Handle<Name> name,
12989 PropertyAttributes* attributes) { 13189 PropertyAttributes* attributes) {
13190 Isolate* isolate = object->GetIsolate();
13191
12990 // TODO(rossberg): Support symbols in the API. 13192 // TODO(rossberg): Support symbols in the API.
12991 if (name->IsSymbol()) return GetHeap()->undefined_value(); 13193 if (name->IsSymbol()) return isolate->factory()->undefined_value();
12992 13194
12993 Isolate* isolate = GetIsolate(); 13195 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor(), isolate);
12994 InterceptorInfo* interceptor = GetNamedInterceptor(); 13196 Handle<String> name_string = Handle<String>::cast(name);
12995 HandleScope scope(isolate);
12996 Handle<Object> receiver_handle(receiver, isolate);
12997 Handle<JSObject> holder_handle(this);
12998 Handle<String> name_handle(String::cast(name));
12999 13197
13000 if (!interceptor->getter()->IsUndefined()) { 13198 if (!interceptor->getter()->IsUndefined()) {
13001 v8::NamedPropertyGetterCallback getter = 13199 v8::NamedPropertyGetterCallback getter =
13002 v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter()); 13200 v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter());
13003 LOG(isolate, 13201 LOG(isolate,
13004 ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name)); 13202 ApiNamedPropertyAccess("interceptor-named-get", *object, *name));
13005 PropertyCallbackArguments 13203 PropertyCallbackArguments
13006 args(isolate, interceptor->data(), receiver, this); 13204 args(isolate, interceptor->data(), *receiver, *object);
13007 v8::Handle<v8::Value> result = 13205 v8::Handle<v8::Value> result =
13008 args.Call(getter, v8::Utils::ToLocal(name_handle)); 13206 args.Call(getter, v8::Utils::ToLocal(name_string));
13009 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 13207 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
13010 if (!result.IsEmpty()) { 13208 if (!result.IsEmpty()) {
13011 *attributes = NONE; 13209 *attributes = NONE;
13012 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); 13210 Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
13013 result_internal->VerifyApiCallResultType(); 13211 result_internal->VerifyApiCallResultType();
13014 return *result_internal; 13212 // Rebox handle to escape this scope.
13213 return handle(*result_internal, isolate);
13015 } 13214 }
13016 } 13215 }
13017 13216
13018 MaybeObject* result = holder_handle->GetPropertyPostInterceptor( 13217 return GetPropertyPostInterceptor(object, receiver, name, attributes);
13019 *receiver_handle,
13020 *name_handle,
13021 attributes);
13022 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
13023 return result;
13024 } 13218 }
13025 13219
13026 13220
13027 bool JSObject::HasRealNamedProperty(Isolate* isolate, Name* key) { 13221 bool JSObject::HasRealNamedProperty(Handle<JSObject> object,
13222 Handle<Name> key) {
13223 Isolate* isolate = object->GetIsolate();
13224 SealHandleScope shs(isolate);
13028 // Check access rights if needed. 13225 // Check access rights if needed.
13029 if (IsAccessCheckNeeded()) { 13226 if (object->IsAccessCheckNeeded()) {
13030 if (!isolate->MayNamedAccess(this, key, v8::ACCESS_HAS)) { 13227 if (!isolate->MayNamedAccess(*object, *key, v8::ACCESS_HAS)) {
13031 isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS); 13228 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS);
13032 return false; 13229 return false;
13033 } 13230 }
13034 } 13231 }
13035 13232
13036 LookupResult result(isolate); 13233 LookupResult result(isolate);
13037 LocalLookupRealNamedProperty(key, &result); 13234 object->LocalLookupRealNamedProperty(*key, &result);
13038 return result.IsFound() && !result.IsInterceptor(); 13235 return result.IsFound() && !result.IsInterceptor();
13039 } 13236 }
13040 13237
13041 13238
13042 bool JSObject::HasRealElementProperty(Isolate* isolate, uint32_t index) { 13239 bool JSObject::HasRealElementProperty(Handle<JSObject> object, uint32_t index) {
13240 Isolate* isolate = object->GetIsolate();
13241 SealHandleScope shs(isolate);
13043 // Check access rights if needed. 13242 // Check access rights if needed.
13044 if (IsAccessCheckNeeded()) { 13243 if (object->IsAccessCheckNeeded()) {
13045 if (!isolate->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { 13244 if (!isolate->MayIndexedAccess(*object, index, v8::ACCESS_HAS)) {
13046 isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS); 13245 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS);
13047 return false; 13246 return false;
13048 } 13247 }
13049 } 13248 }
13050 13249
13051 if (IsJSGlobalProxy()) { 13250 if (object->IsJSGlobalProxy()) {
13052 Object* proto = GetPrototype(); 13251 HandleScope scope(isolate);
13252 Handle<Object> proto(object->GetPrototype(), isolate);
13053 if (proto->IsNull()) return false; 13253 if (proto->IsNull()) return false;
13054 ASSERT(proto->IsJSGlobalObject()); 13254 ASSERT(proto->IsJSGlobalObject());
13055 return JSObject::cast(proto)->HasRealElementProperty(isolate, index); 13255 return HasRealElementProperty(Handle<JSObject>::cast(proto), index);
13056 } 13256 }
13057 13257
13058 return GetElementAttributeWithoutInterceptor(this, index, false) != ABSENT; 13258 return object->GetElementAttributeWithoutInterceptor(
13259 *object, index, false) != ABSENT;
13059 } 13260 }
13060 13261
13061 13262
13062 bool JSObject::HasRealNamedCallbackProperty(Isolate* isolate, Name* key) { 13263 bool JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
13264 Handle<Name> key) {
13265 Isolate* isolate = object->GetIsolate();
13266 SealHandleScope shs(isolate);
13063 // Check access rights if needed. 13267 // Check access rights if needed.
13064 if (IsAccessCheckNeeded()) { 13268 if (object->IsAccessCheckNeeded()) {
13065 if (!isolate->MayNamedAccess(this, key, v8::ACCESS_HAS)) { 13269 if (!isolate->MayNamedAccess(*object, *key, v8::ACCESS_HAS)) {
13066 isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS); 13270 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS);
13067 return false; 13271 return false;
13068 } 13272 }
13069 } 13273 }
13070 13274
13071 LookupResult result(isolate); 13275 LookupResult result(isolate);
13072 LocalLookupRealNamedProperty(key, &result); 13276 object->LocalLookupRealNamedProperty(*key, &result);
13073 return result.IsPropertyCallbacks(); 13277 return result.IsPropertyCallbacks();
13074 } 13278 }
13075 13279
13076 13280
13077 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { 13281 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) {
13078 if (HasFastProperties()) { 13282 if (HasFastProperties()) {
13079 Map* map = this->map(); 13283 Map* map = this->map();
13080 if (filter == NONE) return map->NumberOfOwnDescriptors(); 13284 if (filter == NONE) return map->NumberOfOwnDescriptors();
13081 if (filter & DONT_ENUM) { 13285 if (filter & DONT_ENUM) {
13082 int result = map->EnumLength(); 13286 int result = map->EnumLength();
(...skipping 1005 matching lines...) Expand 10 before | Expand all | Expand 10 after
14088 template 14292 template
14089 int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements(); 14293 int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements();
14090 14294
14091 template 14295 template
14092 int Dictionary<NameDictionaryShape, Name*>::NumberOfEnumElements(); 14296 int Dictionary<NameDictionaryShape, Name*>::NumberOfEnumElements();
14093 14297
14094 template 14298 template
14095 int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t); 14299 int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t);
14096 14300
14097 14301
14302 Handle<Object> JSObject::PrepareSlowElementsForSort(
14303 Handle<JSObject> object, uint32_t limit) {
14304 CALL_HEAP_FUNCTION(object->GetIsolate(),
14305 object->PrepareSlowElementsForSort(limit),
14306 Object);
14307 }
14308
14309
14098 // Collates undefined and unexisting elements below limit from position 14310 // Collates undefined and unexisting elements below limit from position
14099 // zero of the elements. The object stays in Dictionary mode. 14311 // zero of the elements. The object stays in Dictionary mode.
14100 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { 14312 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
14101 ASSERT(HasDictionaryElements()); 14313 ASSERT(HasDictionaryElements());
14102 // Must stay in dictionary mode, either because of requires_slow_elements, 14314 // Must stay in dictionary mode, either because of requires_slow_elements,
14103 // or because we are not going to sort (and therefore compact) all of the 14315 // or because we are not going to sort (and therefore compact) all of the
14104 // elements. 14316 // elements.
14105 SeededNumberDictionary* dict = element_dictionary(); 14317 SeededNumberDictionary* dict = element_dictionary();
14106 HeapNumber* result_double = NULL; 14318 HeapNumber* result_double = NULL;
14107 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { 14319 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
14190 ASSERT_NE(NULL, result_double); 14402 ASSERT_NE(NULL, result_double);
14191 result_double->set_value(static_cast<double>(result)); 14403 result_double->set_value(static_cast<double>(result));
14192 return result_double; 14404 return result_double;
14193 } 14405 }
14194 14406
14195 14407
14196 // Collects all defined (non-hole) and non-undefined (array) elements at 14408 // Collects all defined (non-hole) and non-undefined (array) elements at
14197 // the start of the elements array. 14409 // the start of the elements array.
14198 // If the object is in dictionary mode, it is converted to fast elements 14410 // If the object is in dictionary mode, it is converted to fast elements
14199 // mode. 14411 // mode.
14200 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { 14412 Handle<Object> JSObject::PrepareElementsForSort(Handle<JSObject> object,
14201 Heap* heap = GetHeap(); 14413 uint32_t limit) {
14414 Isolate* isolate = object->GetIsolate();
14202 14415
14203 ASSERT(!map()->is_observed()); 14416 ASSERT(!object->map()->is_observed());
14204 if (HasDictionaryElements()) { 14417 if (object->HasDictionaryElements()) {
14205 // Convert to fast elements containing only the existing properties. 14418 // Convert to fast elements containing only the existing properties.
14206 // Ordering is irrelevant, since we are going to sort anyway. 14419 // Ordering is irrelevant, since we are going to sort anyway.
14207 SeededNumberDictionary* dict = element_dictionary(); 14420 Handle<SeededNumberDictionary> dict(object->element_dictionary());
14208 if (IsJSArray() || dict->requires_slow_elements() || 14421 if (object->IsJSArray() || dict->requires_slow_elements() ||
14209 dict->max_number_key() >= limit) { 14422 dict->max_number_key() >= limit) {
14210 return PrepareSlowElementsForSort(limit); 14423 return JSObject::PrepareSlowElementsForSort(object, limit);
14211 } 14424 }
14212 // Convert to fast elements. 14425 // Convert to fast elements.
14213 14426
14214 Object* obj; 14427 Handle<Map> new_map =
14215 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(), 14428 JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS);
14216 FAST_HOLEY_ELEMENTS);
14217 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
14218 Map* new_map = Map::cast(obj);
14219 14429
14220 PretenureFlag tenure = heap->InNewSpace(this) ? NOT_TENURED: TENURED; 14430 PretenureFlag tenure = isolate->heap()->InNewSpace(*object) ?
14221 Object* new_array; 14431 NOT_TENURED: TENURED;
14222 { MaybeObject* maybe_new_array = 14432 Handle<FixedArray> fast_elements =
14223 heap->AllocateFixedArray(dict->NumberOfElements(), tenure); 14433 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure);
14224 if (!maybe_new_array->ToObject(&new_array)) return maybe_new_array; 14434 dict->CopyValuesTo(*fast_elements);
14225 } 14435 object->ValidateElements();
14226 FixedArray* fast_elements = FixedArray::cast(new_array);
14227 dict->CopyValuesTo(fast_elements);
14228 ValidateElements();
14229 14436
14230 set_map_and_elements(new_map, fast_elements); 14437 object->set_map_and_elements(*new_map, *fast_elements);
14231 } else if (HasExternalArrayElements()) { 14438 } else if (object->HasExternalArrayElements()) {
14232 // External arrays cannot have holes or undefined elements. 14439 // External arrays cannot have holes or undefined elements.
14233 return Smi::FromInt(ExternalArray::cast(elements())->length()); 14440 return handle(Smi::FromInt(
14234 } else if (!HasFastDoubleElements()) { 14441 ExternalArray::cast(object->elements())->length()), isolate);
14235 Object* obj; 14442 } else if (!object->HasFastDoubleElements()) {
14236 { MaybeObject* maybe_obj = EnsureWritableFastElements(); 14443 JSObject::EnsureWritableFastElements(object);
14237 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
14238 }
14239 } 14444 }
14240 ASSERT(HasFastSmiOrObjectElements() || HasFastDoubleElements()); 14445 ASSERT(object->HasFastSmiOrObjectElements() ||
14446 object->HasFastDoubleElements());
14241 14447
14242 // Collect holes at the end, undefined before that and the rest at the 14448 // Collect holes at the end, undefined before that and the rest at the
14243 // start, and return the number of non-hole, non-undefined values. 14449 // start, and return the number of non-hole, non-undefined values.
14244 14450
14245 FixedArrayBase* elements_base = FixedArrayBase::cast(this->elements()); 14451 Handle<FixedArrayBase> elements_base(object->elements());
14246 uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); 14452 uint32_t elements_length = static_cast<uint32_t>(elements_base->length());
14247 if (limit > elements_length) { 14453 if (limit > elements_length) {
14248 limit = elements_length ; 14454 limit = elements_length ;
14249 } 14455 }
14250 if (limit == 0) { 14456 if (limit == 0) {
14251 return Smi::FromInt(0); 14457 return handle(Smi::FromInt(0), isolate);
14252 }
14253
14254 HeapNumber* result_double = NULL;
14255 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
14256 // Pessimistically allocate space for return value before
14257 // we start mutating the array.
14258 Object* new_double;
14259 { MaybeObject* maybe_new_double = heap->AllocateHeapNumber(0.0);
14260 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double;
14261 }
14262 result_double = HeapNumber::cast(new_double);
14263 } 14458 }
14264 14459
14265 uint32_t result = 0; 14460 uint32_t result = 0;
14266 if (elements_base->map() == heap->fixed_double_array_map()) { 14461 if (elements_base->map() == isolate->heap()->fixed_double_array_map()) {
14267 FixedDoubleArray* elements = FixedDoubleArray::cast(elements_base); 14462 FixedDoubleArray* elements = FixedDoubleArray::cast(*elements_base);
14268 // Split elements into defined and the_hole, in that order. 14463 // Split elements into defined and the_hole, in that order.
14269 unsigned int holes = limit; 14464 unsigned int holes = limit;
14270 // Assume most arrays contain no holes and undefined values, so minimize the 14465 // Assume most arrays contain no holes and undefined values, so minimize the
14271 // number of stores of non-undefined, non-the-hole values. 14466 // number of stores of non-undefined, non-the-hole values.
14272 for (unsigned int i = 0; i < holes; i++) { 14467 for (unsigned int i = 0; i < holes; i++) {
14273 if (elements->is_the_hole(i)) { 14468 if (elements->is_the_hole(i)) {
14274 holes--; 14469 holes--;
14275 } else { 14470 } else {
14276 continue; 14471 continue;
14277 } 14472 }
14278 // Position i needs to be filled. 14473 // Position i needs to be filled.
14279 while (holes > i) { 14474 while (holes > i) {
14280 if (elements->is_the_hole(holes)) { 14475 if (elements->is_the_hole(holes)) {
14281 holes--; 14476 holes--;
14282 } else { 14477 } else {
14283 elements->set(i, elements->get_scalar(holes)); 14478 elements->set(i, elements->get_scalar(holes));
14284 break; 14479 break;
14285 } 14480 }
14286 } 14481 }
14287 } 14482 }
14288 result = holes; 14483 result = holes;
14289 while (holes < limit) { 14484 while (holes < limit) {
14290 elements->set_the_hole(holes); 14485 elements->set_the_hole(holes);
14291 holes++; 14486 holes++;
14292 } 14487 }
14293 } else { 14488 } else {
14294 FixedArray* elements = FixedArray::cast(elements_base); 14489 FixedArray* elements = FixedArray::cast(*elements_base);
14295 DisallowHeapAllocation no_gc; 14490 DisallowHeapAllocation no_gc;
14296 14491
14297 // Split elements into defined, undefined and the_hole, in that order. Only 14492 // Split elements into defined, undefined and the_hole, in that order. Only
14298 // count locations for undefined and the hole, and fill them afterwards. 14493 // count locations for undefined and the hole, and fill them afterwards.
14299 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_gc); 14494 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_gc);
14300 unsigned int undefs = limit; 14495 unsigned int undefs = limit;
14301 unsigned int holes = limit; 14496 unsigned int holes = limit;
14302 // Assume most arrays contain no holes and undefined values, so minimize the 14497 // Assume most arrays contain no holes and undefined values, so minimize the
14303 // number of stores of non-undefined, non-the-hole values. 14498 // number of stores of non-undefined, non-the-hole values.
14304 for (unsigned int i = 0; i < undefs; i++) { 14499 for (unsigned int i = 0; i < undefs; i++) {
(...skipping 24 matching lines...) Expand all
14329 while (undefs < holes) { 14524 while (undefs < holes) {
14330 elements->set_undefined(undefs); 14525 elements->set_undefined(undefs);
14331 undefs++; 14526 undefs++;
14332 } 14527 }
14333 while (holes < limit) { 14528 while (holes < limit) {
14334 elements->set_the_hole(holes); 14529 elements->set_the_hole(holes);
14335 holes++; 14530 holes++;
14336 } 14531 }
14337 } 14532 }
14338 14533
14339 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { 14534 return isolate->factory()->NewNumberFromUint(result);
14340 return Smi::FromInt(static_cast<int>(result));
14341 }
14342 ASSERT_NE(NULL, result_double);
14343 result_double->set_value(static_cast<double>(result));
14344 return result_double;
14345 } 14535 }
14346 14536
14347 14537
14348 ExternalArrayType JSTypedArray::type() { 14538 ExternalArrayType JSTypedArray::type() {
14349 switch (elements()->map()->instance_type()) { 14539 switch (elements()->map()->instance_type()) {
14350 case EXTERNAL_BYTE_ARRAY_TYPE: 14540 case EXTERNAL_BYTE_ARRAY_TYPE:
14351 return kExternalByteArray; 14541 return kExternalByteArray;
14352 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: 14542 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
14353 return kExternalUnsignedByteArray; 14543 return kExternalUnsignedByteArray;
14354 case EXTERNAL_SHORT_ARRAY_TYPE: 14544 case EXTERNAL_SHORT_ARRAY_TYPE:
(...skipping 1785 matching lines...) Expand 10 before | Expand all | Expand 10 after
16140 return static_cast<Type*>(type_raw()); 16330 return static_cast<Type*>(type_raw());
16141 } 16331 }
16142 16332
16143 16333
16144 void PropertyCell::set_type(Type* type, WriteBarrierMode ignored) { 16334 void PropertyCell::set_type(Type* type, WriteBarrierMode ignored) {
16145 ASSERT(IsPropertyCell()); 16335 ASSERT(IsPropertyCell());
16146 set_type_raw(type, ignored); 16336 set_type_raw(type, ignored);
16147 } 16337 }
16148 16338
16149 16339
16150 Type* PropertyCell::UpdateType(Handle<PropertyCell> cell, 16340 Handle<Type> PropertyCell::UpdatedType(Handle<PropertyCell> cell,
16151 Handle<Object> value) { 16341 Handle<Object> value) {
16152 Isolate* isolate = cell->GetIsolate(); 16342 Isolate* isolate = cell->GetIsolate();
16153 Handle<Type> old_type(cell->type(), isolate); 16343 Handle<Type> old_type(cell->type(), isolate);
16154 // TODO(2803): Do not track ConsString as constant because they cannot be 16344 // TODO(2803): Do not track ConsString as constant because they cannot be
16155 // embedded into code. 16345 // embedded into code.
16156 Handle<Type> new_type(value->IsConsString() || value->IsTheHole() 16346 Handle<Type> new_type(value->IsConsString() || value->IsTheHole()
16157 ? Type::Any() 16347 ? Type::Any()
16158 : Type::Constant(value, isolate), isolate); 16348 : Type::Constant(value, isolate), isolate);
16159 16349
16160 if (new_type->Is(old_type)) { 16350 if (new_type->Is(old_type)) {
16161 return *old_type; 16351 return old_type;
16162 } 16352 }
16163 16353
16164 cell->dependent_code()->DeoptimizeDependentCodeGroup( 16354 cell->dependent_code()->DeoptimizeDependentCodeGroup(
16165 isolate, DependentCode::kPropertyCellChangedGroup); 16355 isolate, DependentCode::kPropertyCellChangedGroup);
16166 16356
16167 if (old_type->Is(Type::None()) || old_type->Is(Type::Undefined())) { 16357 if (old_type->Is(Type::None()) || old_type->Is(Type::Undefined())) {
16168 return *new_type; 16358 return new_type;
16169 } 16359 }
16170 16360
16171 return Type::Any(); 16361 return handle(Type::Any(), isolate);
16172 } 16362 }
16173 16363
16174 16364
16175 void PropertyCell::SetValueInferType(Handle<PropertyCell> cell, 16365 void PropertyCell::SetValueInferType(Handle<PropertyCell> cell,
16176 Handle<Object> value, 16366 Handle<Object> value) {
16177 WriteBarrierMode mode) { 16367 cell->set_value(*value);
16178 CALL_HEAP_FUNCTION_VOID(cell->GetIsolate(), 16368 if (!Type::Any()->Is(cell->type())) {
16179 cell->SetValueInferType(*value, mode)); 16369 Handle<Type> new_type = UpdatedType(cell, value);
16370 cell->set_type(*new_type);
16371 }
16180 } 16372 }
16181 16373
16182 16374
16183 MaybeObject* PropertyCell::SetValueInferType(Object* value,
16184 WriteBarrierMode ignored) {
16185 set_value(value, ignored);
16186 if (!Type::Any()->Is(type())) {
16187 IdempotentPointerToHandleCodeTrampoline trampoline(GetIsolate());
16188 MaybeObject* maybe_type = trampoline.CallWithReturnValue(
16189 &PropertyCell::UpdateType,
16190 Handle<PropertyCell>(this),
16191 Handle<Object>(value, GetIsolate()));
16192 Type* new_type = NULL;
16193 if (!maybe_type->To(&new_type)) return maybe_type;
16194 set_type(new_type);
16195 }
16196 return value;
16197 }
16198
16199
16200 void PropertyCell::AddDependentCompilationInfo(CompilationInfo* info) { 16375 void PropertyCell::AddDependentCompilationInfo(CompilationInfo* info) {
16201 Handle<DependentCode> dep(dependent_code()); 16376 Handle<DependentCode> dep(dependent_code());
16202 Handle<DependentCode> codes = 16377 Handle<DependentCode> codes =
16203 DependentCode::Insert(dep, DependentCode::kPropertyCellChangedGroup, 16378 DependentCode::Insert(dep, DependentCode::kPropertyCellChangedGroup,
16204 info->object_wrapper()); 16379 info->object_wrapper());
16205 if (*codes != dependent_code()) set_dependent_code(*codes); 16380 if (*codes != dependent_code()) set_dependent_code(*codes);
16206 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( 16381 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add(
16207 Handle<HeapObject>(this), info->zone()); 16382 Handle<HeapObject>(this), info->zone());
16208 } 16383 }
16209 16384
(...skipping 11 matching lines...) Expand all
16221 #define ERROR_MESSAGES_TEXTS(C, T) T, 16396 #define ERROR_MESSAGES_TEXTS(C, T) T,
16222 static const char* error_messages_[] = { 16397 static const char* error_messages_[] = {
16223 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16398 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16224 }; 16399 };
16225 #undef ERROR_MESSAGES_TEXTS 16400 #undef ERROR_MESSAGES_TEXTS
16226 return error_messages_[reason]; 16401 return error_messages_[reason];
16227 } 16402 }
16228 16403
16229 16404
16230 } } // namespace v8::internal 16405 } } // 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