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

Side by Side Diff: src/objects.cc

Issue 39973003: Merge bleeding_edge. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: again Created 7 years, 1 month 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<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
332 Object* structure, 347 Handle<Object> receiver,
333 Name* name) { 348 Handle<Object> structure,
349 Handle<Name> name) {
334 Isolate* isolate = name->GetIsolate(); 350 Isolate* isolate = name->GetIsolate();
335 // To accommodate both the old and the new api we switch on the 351 // To accommodate both the old and the new api we switch on the
336 // data structure used to store the callbacks. Eventually foreign 352 // data structure used to store the callbacks. Eventually foreign
337 // callbacks should be phased out. 353 // callbacks should be phased out.
338 if (structure->IsForeign()) { 354 if (structure->IsForeign()) {
339 AccessorDescriptor* callback = 355 AccessorDescriptor* callback =
340 reinterpret_cast<AccessorDescriptor*>( 356 reinterpret_cast<AccessorDescriptor*>(
341 Foreign::cast(structure)->foreign_address()); 357 Handle<Foreign>::cast(structure)->foreign_address());
342 MaybeObject* value = (callback->getter)(isolate, receiver, callback->data); 358 CALL_HEAP_FUNCTION(isolate,
343 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 359 (callback->getter)(isolate, *receiver, callback->data),
344 return value; 360 Object);
345 } 361 }
346 362
347 // api style callbacks. 363 // api style callbacks.
348 if (structure->IsAccessorInfo()) { 364 if (structure->IsAccessorInfo()) {
349 if (!AccessorInfo::cast(structure)->IsCompatibleReceiver(receiver)) { 365 Handle<AccessorInfo> accessor_info = Handle<AccessorInfo>::cast(structure);
350 Handle<Object> name_handle(name, isolate); 366 if (!accessor_info->IsCompatibleReceiver(*receiver)) {
351 Handle<Object> receiver_handle(receiver, isolate); 367 Handle<Object> args[2] = { name, receiver };
352 Handle<Object> args[2] = { name_handle, receiver_handle };
353 Handle<Object> error = 368 Handle<Object> error =
354 isolate->factory()->NewTypeError("incompatible_method_receiver", 369 isolate->factory()->NewTypeError("incompatible_method_receiver",
355 HandleVector(args, 370 HandleVector(args,
356 ARRAY_SIZE(args))); 371 ARRAY_SIZE(args)));
357 return isolate->Throw(*error); 372 isolate->Throw(*error);
373 return Handle<Object>::null();
358 } 374 }
359 // TODO(rossberg): Handling symbols in the API requires changing the API, 375 // TODO(rossberg): Handling symbols in the API requires changing the API,
360 // so we do not support it for now. 376 // so we do not support it for now.
361 if (name->IsSymbol()) return isolate->heap()->undefined_value(); 377 if (name->IsSymbol()) return isolate->factory()->undefined_value();
362 if (structure->IsDeclaredAccessorInfo()) { 378 if (structure->IsDeclaredAccessorInfo()) {
363 return GetDeclaredAccessorProperty(receiver, 379 CALL_HEAP_FUNCTION(
364 DeclaredAccessorInfo::cast(structure), 380 isolate,
365 isolate); 381 GetDeclaredAccessorProperty(*receiver,
382 DeclaredAccessorInfo::cast(*structure),
383 isolate),
384 Object);
366 } 385 }
367 ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(structure); 386
368 Object* fun_obj = data->getter(); 387 Handle<ExecutableAccessorInfo> data =
388 Handle<ExecutableAccessorInfo>::cast(structure);
369 v8::AccessorGetterCallback call_fun = 389 v8::AccessorGetterCallback call_fun =
370 v8::ToCData<v8::AccessorGetterCallback>(fun_obj); 390 v8::ToCData<v8::AccessorGetterCallback>(data->getter());
371 if (call_fun == NULL) return isolate->heap()->undefined_value(); 391 if (call_fun == NULL) return isolate->factory()->undefined_value();
392
372 HandleScope scope(isolate); 393 HandleScope scope(isolate);
373 JSObject* self = JSObject::cast(receiver); 394 Handle<JSObject> self = Handle<JSObject>::cast(receiver);
374 Handle<String> key(String::cast(name)); 395 Handle<String> key = Handle<String>::cast(name);
375 LOG(isolate, ApiNamedPropertyAccess("load", self, name)); 396 LOG(isolate, ApiNamedPropertyAccess("load", *self, *name));
376 PropertyCallbackArguments args(isolate, data->data(), self, this); 397 PropertyCallbackArguments args(isolate, data->data(), *self, *object);
377 v8::Handle<v8::Value> result = 398 v8::Handle<v8::Value> result =
378 args.Call(call_fun, v8::Utils::ToLocal(key)); 399 args.Call(call_fun, v8::Utils::ToLocal(key));
379 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 400 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
380 if (result.IsEmpty()) { 401 if (result.IsEmpty()) {
381 return isolate->heap()->undefined_value(); 402 return isolate->factory()->undefined_value();
382 } 403 }
383 Object* return_value = *v8::Utils::OpenHandle(*result); 404 Handle<Object> return_value = v8::Utils::OpenHandle(*result);
384 return_value->VerifyApiCallResultType(); 405 return_value->VerifyApiCallResultType();
385 return return_value; 406 return scope.CloseAndEscape(return_value);
386 } 407 }
387 408
388 // __defineGetter__ callback 409 // __defineGetter__ callback
389 if (structure->IsAccessorPair()) { 410 Handle<Object> getter(Handle<AccessorPair>::cast(structure)->getter(),
390 Object* getter = AccessorPair::cast(structure)->getter(); 411 isolate);
391 if (getter->IsSpecFunction()) { 412 if (getter->IsSpecFunction()) {
392 // TODO(rossberg): nicer would be to cast to some JSCallable here... 413 // TODO(rossberg): nicer would be to cast to some JSCallable here...
393 return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter)); 414 CALL_HEAP_FUNCTION(
394 } 415 isolate,
395 // Getter is not a function. 416 object->GetPropertyWithDefinedGetter(*receiver,
396 return isolate->heap()->undefined_value(); 417 JSReceiver::cast(*getter)),
418 Object);
397 } 419 }
398 420 // Getter is not a function.
399 UNREACHABLE(); 421 return isolate->factory()->undefined_value();
400 return NULL;
401 } 422 }
402 423
403 424
404 MaybeObject* JSProxy::GetPropertyWithHandler(Object* receiver_raw, 425 MaybeObject* JSProxy::GetPropertyWithHandler(Object* receiver_raw,
405 Name* name_raw) { 426 Name* name_raw) {
406 Isolate* isolate = GetIsolate(); 427 Isolate* isolate = GetIsolate();
407 HandleScope scope(isolate); 428 HandleScope scope(isolate);
408 Handle<Object> receiver(receiver_raw, isolate); 429 Handle<Object> receiver(receiver_raw, isolate);
409 Handle<Object> name(name_raw, isolate); 430 Handle<Object> name(name_raw, isolate);
410 431
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 bool has_pending_exception; 507 bool has_pending_exception;
487 Handle<Object> result = Execution::Call( 508 Handle<Object> result = Execution::Call(
488 isolate, fun, self, 0, NULL, &has_pending_exception, true); 509 isolate, fun, self, 0, NULL, &has_pending_exception, true);
489 // Check for pending exception and return the result. 510 // Check for pending exception and return the result.
490 if (has_pending_exception) return Failure::Exception(); 511 if (has_pending_exception) return Failure::Exception();
491 return *result; 512 return *result;
492 } 513 }
493 514
494 515
495 // Only deal with CALLBACKS and INTERCEPTOR 516 // Only deal with CALLBACKS and INTERCEPTOR
496 MaybeObject* JSObject::GetPropertyWithFailedAccessCheck( 517 Handle<Object> JSObject::GetPropertyWithFailedAccessCheck(
497 Object* receiver, 518 Handle<JSObject> object,
519 Handle<Object> receiver,
498 LookupResult* result, 520 LookupResult* result,
499 Name* name, 521 Handle<Name> name,
500 PropertyAttributes* attributes) { 522 PropertyAttributes* attributes) {
523 Isolate* isolate = name->GetIsolate();
501 if (result->IsProperty()) { 524 if (result->IsProperty()) {
502 switch (result->type()) { 525 switch (result->type()) {
503 case CALLBACKS: { 526 case CALLBACKS: {
504 // Only allow API accessors. 527 // Only allow API accessors.
505 Object* obj = result->GetCallbackObject(); 528 Handle<Object> callback_obj(result->GetCallbackObject(), isolate);
506 if (obj->IsAccessorInfo()) { 529 if (callback_obj->IsAccessorInfo()) {
507 AccessorInfo* info = AccessorInfo::cast(obj); 530 if (!AccessorInfo::cast(*callback_obj)->all_can_read()) break;
508 if (info->all_can_read()) { 531 *attributes = result->GetAttributes();
509 *attributes = result->GetAttributes(); 532 // Fall through to GetPropertyWithCallback.
510 return result->holder()->GetPropertyWithCallback( 533 } else if (callback_obj->IsAccessorPair()) {
511 receiver, result->GetCallbackObject(), name); 534 if (!AccessorPair::cast(*callback_obj)->all_can_read()) break;
512 } 535 // Fall through to GetPropertyWithCallback.
513 } else if (obj->IsAccessorPair()) { 536 } else {
514 AccessorPair* pair = AccessorPair::cast(obj); 537 break;
515 if (pair->all_can_read()) {
516 return result->holder()->GetPropertyWithCallback(
517 receiver, result->GetCallbackObject(), name);
518 }
519 } 538 }
520 break; 539 Handle<JSObject> holder(result->holder(), isolate);
540 return GetPropertyWithCallback(holder, receiver, callback_obj, name);
521 } 541 }
522 case NORMAL: 542 case NORMAL:
523 case FIELD: 543 case FIELD:
524 case CONSTANT: { 544 case CONSTANT: {
525 // Search ALL_CAN_READ accessors in prototype chain. 545 // Search ALL_CAN_READ accessors in prototype chain.
526 LookupResult r(GetIsolate()); 546 LookupResult r(isolate);
527 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); 547 result->holder()->LookupRealNamedPropertyInPrototypes(*name, &r);
528 if (r.IsProperty()) { 548 if (r.IsProperty()) {
529 return GetPropertyWithFailedAccessCheck(receiver, 549 return GetPropertyWithFailedAccessCheck(
530 &r, 550 object, receiver, &r, name, attributes);
531 name,
532 attributes);
533 } 551 }
534 break; 552 break;
535 } 553 }
536 case INTERCEPTOR: { 554 case INTERCEPTOR: {
537 // If the object has an interceptor, try real named properties. 555 // If the object has an interceptor, try real named properties.
538 // No access check in GetPropertyAttributeWithInterceptor. 556 // No access check in GetPropertyAttributeWithInterceptor.
539 LookupResult r(GetIsolate()); 557 LookupResult r(isolate);
540 result->holder()->LookupRealNamedProperty(name, &r); 558 result->holder()->LookupRealNamedProperty(*name, &r);
541 if (r.IsProperty()) { 559 if (r.IsProperty()) {
542 return GetPropertyWithFailedAccessCheck(receiver, 560 return GetPropertyWithFailedAccessCheck(
543 &r, 561 object, receiver, &r, name, attributes);
544 name,
545 attributes);
546 } 562 }
547 break; 563 break;
548 } 564 }
549 default: 565 default:
550 UNREACHABLE(); 566 UNREACHABLE();
551 } 567 }
552 } 568 }
553 569
554 // No accessible property found. 570 // No accessible property found.
555 *attributes = ABSENT; 571 *attributes = ABSENT;
556 Heap* heap = name->GetHeap(); 572 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_GET);
557 Isolate* isolate = heap->isolate(); 573 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
558 isolate->ReportFailedAccessCheck(this, v8::ACCESS_GET); 574 return isolate->factory()->undefined_value();
559 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
560 return heap->undefined_value();
561 } 575 }
562 576
563 577
564 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( 578 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck(
565 Object* receiver, 579 Object* receiver,
566 LookupResult* result, 580 LookupResult* result,
567 Name* name, 581 Name* name,
568 bool continue_search) { 582 bool continue_search) {
569 if (result->IsProperty()) { 583 if (result->IsProperty()) {
570 switch (result->type()) { 584 switch (result->type()) {
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 LookupResult* result, 810 LookupResult* result,
797 Handle<Name> key, 811 Handle<Name> key,
798 PropertyAttributes* attributes) { 812 PropertyAttributes* attributes) {
799 Isolate* isolate = result->isolate(); 813 Isolate* isolate = result->isolate();
800 CALL_HEAP_FUNCTION_PASS_EXCEPTION( 814 CALL_HEAP_FUNCTION_PASS_EXCEPTION(
801 isolate, 815 isolate,
802 object->GetProperty(*receiver, result, *key, attributes)); 816 object->GetProperty(*receiver, result, *key, attributes));
803 } 817 }
804 818
805 819
820 // TODO(yangguo): handlify this and get rid of.
806 MaybeObject* Object::GetProperty(Object* receiver, 821 MaybeObject* Object::GetProperty(Object* receiver,
807 LookupResult* result, 822 LookupResult* result,
808 Name* name, 823 Name* name,
809 PropertyAttributes* attributes) { 824 PropertyAttributes* attributes) {
810 Isolate* isolate = name->GetIsolate(); 825 Isolate* isolate = name->GetIsolate();
811 Heap* heap = isolate->heap(); 826 Heap* heap = isolate->heap();
812 827
813 #ifdef DEBUG 828 #ifdef DEBUG
814 // TODO(mstarzinger): Only because of the AssertNoContextChange, drop as soon 829 // TODO(mstarzinger): Only because of the AssertNoContextChange, drop as soon
815 // as this method has been fully handlified. 830 // as this method has been fully handlified.
(...skipping 18 matching lines...) Expand all
834 ASSERT(this != this->GetPrototype(isolate)); 849 ASSERT(this != this->GetPrototype(isolate));
835 for (Object* current = this; 850 for (Object* current = this;
836 true; 851 true;
837 current = current->GetPrototype(isolate)) { 852 current = current->GetPrototype(isolate)) {
838 if (current->IsAccessCheckNeeded()) { 853 if (current->IsAccessCheckNeeded()) {
839 // Check if we're allowed to read from the current object. Note 854 // 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 855 // that even though we may not actually end up loading the named
841 // property from the current object, we still check that we have 856 // property from the current object, we still check that we have
842 // access to it. 857 // access to it.
843 JSObject* checked = JSObject::cast(current); 858 JSObject* checked = JSObject::cast(current);
844 if (!heap->isolate()->MayNamedAccess(checked, name, v8::ACCESS_GET)) { 859 if (!isolate->MayNamedAccess(checked, name, v8::ACCESS_GET)) {
845 return checked->GetPropertyWithFailedAccessCheck(receiver, 860 HandleScope scope(isolate);
846 result, 861 Handle<Object> value = JSObject::GetPropertyWithFailedAccessCheck(
847 name, 862 handle(checked, isolate),
848 attributes); 863 handle(receiver, isolate),
864 result,
865 handle(name, isolate),
866 attributes);
867 RETURN_IF_EMPTY_HANDLE(isolate, value);
868 return *value;
849 } 869 }
850 } 870 }
851 // Stop traversing the chain once we reach the last object in the 871 // 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 872 // chain; either the holder of the result or null in case of an
853 // absent property. 873 // absent property.
854 if (current == last) break; 874 if (current == last) break;
855 } 875 }
856 } 876 }
857 877
858 if (!result->IsProperty()) { 878 if (!result->IsProperty()) {
(...skipping 10 matching lines...) Expand all
869 case FIELD: { 889 case FIELD: {
870 MaybeObject* maybe_result = result->holder()->FastPropertyAt( 890 MaybeObject* maybe_result = result->holder()->FastPropertyAt(
871 result->representation(), 891 result->representation(),
872 result->GetFieldIndex().field_index()); 892 result->GetFieldIndex().field_index());
873 if (!maybe_result->To(&value)) return maybe_result; 893 if (!maybe_result->To(&value)) return maybe_result;
874 ASSERT(!value->IsTheHole() || result->IsReadOnly()); 894 ASSERT(!value->IsTheHole() || result->IsReadOnly());
875 return value->IsTheHole() ? heap->undefined_value() : value; 895 return value->IsTheHole() ? heap->undefined_value() : value;
876 } 896 }
877 case CONSTANT: 897 case CONSTANT:
878 return result->GetConstant(); 898 return result->GetConstant();
879 case CALLBACKS: 899 case CALLBACKS: {
880 return result->holder()->GetPropertyWithCallback( 900 HandleScope scope(isolate);
881 receiver, result->GetCallbackObject(), name); 901 Handle<Object> value = JSObject::GetPropertyWithCallback(
902 handle(result->holder(), isolate),
903 handle(receiver, isolate),
904 handle(result->GetCallbackObject(), isolate),
905 handle(name, isolate));
906 RETURN_IF_EMPTY_HANDLE(isolate, value);
907 return *value;
908 }
882 case HANDLER: 909 case HANDLER:
883 return result->proxy()->GetPropertyWithHandler(receiver, name); 910 return result->proxy()->GetPropertyWithHandler(receiver, name);
884 case INTERCEPTOR: 911 case INTERCEPTOR: {
885 return result->holder()->GetPropertyWithInterceptor( 912 HandleScope scope(isolate);
886 receiver, name, attributes); 913 Handle<Object> value = JSObject::GetPropertyWithInterceptor(
914 handle(result->holder(), isolate),
915 handle(receiver, isolate),
916 handle(name, isolate),
917 attributes);
918 RETURN_IF_EMPTY_HANDLE(isolate, value);
919 return *value;
920 }
887 case TRANSITION: 921 case TRANSITION:
888 case NONEXISTENT: 922 case NONEXISTENT:
889 UNREACHABLE(); 923 UNREACHABLE();
890 break; 924 break;
891 } 925 }
892 UNREACHABLE(); 926 UNREACHABLE();
893 return NULL; 927 return NULL;
894 } 928 }
895 929
896 930
(...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after
1697 } 1731 }
1698 break; 1732 break;
1699 } 1733 }
1700 return; 1734 return;
1701 } 1735 }
1702 1736
1703 switch (type) { 1737 switch (type) {
1704 case FIXED_ARRAY_TYPE: 1738 case FIXED_ARRAY_TYPE:
1705 FixedArray::BodyDescriptor::IterateBody(this, object_size, v); 1739 FixedArray::BodyDescriptor::IterateBody(this, object_size, v);
1706 break; 1740 break;
1741 case CONSTANT_POOL_ARRAY_TYPE:
1742 reinterpret_cast<ConstantPoolArray*>(this)->ConstantPoolIterateBody(v);
1743 break;
1707 case FIXED_DOUBLE_ARRAY_TYPE: 1744 case FIXED_DOUBLE_ARRAY_TYPE:
1708 break; 1745 break;
1709 case JS_OBJECT_TYPE: 1746 case JS_OBJECT_TYPE:
1710 case JS_CONTEXT_EXTENSION_OBJECT_TYPE: 1747 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
1711 case JS_GENERATOR_OBJECT_TYPE: 1748 case JS_GENERATOR_OBJECT_TYPE:
1712 case JS_MODULE_TYPE: 1749 case JS_MODULE_TYPE:
1713 case JS_VALUE_TYPE: 1750 case JS_VALUE_TYPE:
1714 case JS_DATE_TYPE: 1751 case JS_DATE_TYPE:
1715 case JS_ARRAY_TYPE: 1752 case JS_ARRAY_TYPE:
1716 case JS_ARRAY_BUFFER_TYPE: 1753 case JS_ARRAY_BUFFER_TYPE:
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
2093 } else { 2130 } else {
2094 // Normalize the object to prevent very large instance descriptors. 2131 // Normalize the object to prevent very large instance descriptors.
2095 // This eliminates unwanted N^2 allocation and lookup behavior. 2132 // This eliminates unwanted N^2 allocation and lookup behavior.
2096 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); 2133 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
2097 AddSlowProperty(object, name, value, attributes); 2134 AddSlowProperty(object, name, value, attributes);
2098 } 2135 }
2099 } else { 2136 } else {
2100 AddSlowProperty(object, name, value, attributes); 2137 AddSlowProperty(object, name, value, attributes);
2101 } 2138 }
2102 2139
2103 if (FLAG_harmony_observation && object->map()->is_observed()) { 2140 if (FLAG_harmony_observation &&
2141 object->map()->is_observed() &&
2142 *name != isolate->heap()->hidden_string()) {
2104 Handle<Object> old_value = isolate->factory()->the_hole_value(); 2143 Handle<Object> old_value = isolate->factory()->the_hole_value();
2105 EnqueueChangeRecord(object, "new", name, old_value); 2144 EnqueueChangeRecord(object, "new", name, old_value);
2106 } 2145 }
2107 2146
2108 return value; 2147 return value;
2109 } 2148 }
2110 2149
2111 2150
2112 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, 2151 void JSObject::EnqueueChangeRecord(Handle<JSObject> object,
2113 const char* type_str, 2152 const char* type_str,
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2244 elms->set_length(len - to_trim); 2283 elms->set_length(len - to_trim);
2245 2284
2246 // Maintain marking consistency for IncrementalMarking. 2285 // Maintain marking consistency for IncrementalMarking.
2247 if (Marking::IsBlack(Marking::MarkBitFrom(elms))) { 2286 if (Marking::IsBlack(Marking::MarkBitFrom(elms))) {
2248 if (trim_mode == FROM_GC) { 2287 if (trim_mode == FROM_GC) {
2249 MemoryChunk::IncrementLiveBytesFromGC(elms->address(), -size_delta); 2288 MemoryChunk::IncrementLiveBytesFromGC(elms->address(), -size_delta);
2250 } else { 2289 } else {
2251 MemoryChunk::IncrementLiveBytesFromMutator(elms->address(), -size_delta); 2290 MemoryChunk::IncrementLiveBytesFromMutator(elms->address(), -size_delta);
2252 } 2291 }
2253 } 2292 }
2293
2294 // The array may not be moved during GC,
2295 // and size has to be adjusted nevertheless.
2296 HeapProfiler* profiler = heap->isolate()->heap_profiler();
2297 if (profiler->is_tracking_allocations()) {
2298 profiler->UpdateObjectSizeEvent(elms->address(), elms->Size());
2299 }
2254 } 2300 }
2255 2301
2256 2302
2257 bool Map::InstancesNeedRewriting(Map* target, 2303 bool Map::InstancesNeedRewriting(Map* target,
2258 int target_number_of_fields, 2304 int target_number_of_fields,
2259 int target_inobject, 2305 int target_inobject,
2260 int target_unused) { 2306 int target_unused) {
2261 // If fields were added (or removed), rewrite the instance. 2307 // If fields were added (or removed), rewrite the instance.
2262 int number_of_fields = NumberOfFields(); 2308 int number_of_fields = NumberOfFields();
2263 ASSERT(target_number_of_fields >= number_of_fields); 2309 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. 2427 // size and install the backing store into the object.
2382 if (external > 0) { 2428 if (external > 0) {
2383 RightTrimFixedArray<FROM_MUTATOR>(isolate->heap(), *array, inobject); 2429 RightTrimFixedArray<FROM_MUTATOR>(isolate->heap(), *array, inobject);
2384 object->set_properties(*array); 2430 object->set_properties(*array);
2385 } 2431 }
2386 2432
2387 object->set_map(*new_map); 2433 object->set_map(*new_map);
2388 } 2434 }
2389 2435
2390 2436
2437 Handle<TransitionArray> Map::AddTransition(Handle<Map> map,
2438 Handle<Name> key,
2439 Handle<Map> target,
2440 SimpleTransitionFlag flag) {
2441 CALL_HEAP_FUNCTION(map->GetIsolate(),
2442 map->AddTransition(*key, *target, flag),
2443 TransitionArray);
2444 }
2445
2446
2391 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object, 2447 void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object,
2392 int modify_index, 2448 int modify_index,
2393 Representation new_representation, 2449 Representation new_representation,
2394 StoreMode store_mode) { 2450 StoreMode store_mode) {
2395 Handle<Map> new_map = Map::GeneralizeRepresentation( 2451 Handle<Map> new_map = Map::GeneralizeRepresentation(
2396 handle(object->map()), modify_index, new_representation, store_mode); 2452 handle(object->map()), modify_index, new_representation, store_mode);
2397 if (object->map() == *new_map) return; 2453 if (object->map() == *new_map) return;
2398 return MigrateToMap(object, new_map); 2454 return MigrateToMap(object, new_map);
2399 } 2455 }
2400 2456
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
2681 for (; descriptor < descriptors; descriptor++) { 2737 for (; descriptor < descriptors; descriptor++) {
2682 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors); 2738 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors);
2683 new_map->set_migration_target(true); 2739 new_map->set_migration_target(true);
2684 } 2740 }
2685 2741
2686 new_map->set_owns_descriptors(true); 2742 new_map->set_owns_descriptors(true);
2687 return new_map; 2743 return new_map;
2688 } 2744 }
2689 2745
2690 2746
2747 // Generalize the representation of all FIELD descriptors.
2748 Handle<Map> Map::GeneralizeAllFieldRepresentations(
2749 Handle<Map> map,
2750 Representation new_representation) {
2751 Handle<DescriptorArray> descriptors(map->instance_descriptors());
2752 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
2753 PropertyDetails details = descriptors->GetDetails(i);
2754 if (details.type() == FIELD) {
2755 map = GeneralizeRepresentation(map, i, new_representation, FORCE_FIELD);
2756 }
2757 }
2758 return map;
2759 }
2760
2761
2691 Map* Map::CurrentMapForDeprecated() { 2762 Map* Map::CurrentMapForDeprecated() {
2692 DisallowHeapAllocation no_allocation; 2763 DisallowHeapAllocation no_allocation;
2693 if (!is_deprecated()) return this; 2764 if (!is_deprecated()) return this;
2694 2765
2695 DescriptorArray* old_descriptors = instance_descriptors(); 2766 DescriptorArray* old_descriptors = instance_descriptors();
2696 2767
2697 int descriptors = NumberOfOwnDescriptors(); 2768 int descriptors = NumberOfOwnDescriptors();
2698 Map* root_map = FindRootMap(); 2769 Map* root_map = FindRootMap();
2699 2770
2700 // Check the state of the root map. 2771 // 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( 4035 Handle<Object> error = isolate->factory()->NewTypeError(
3965 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); 4036 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
3966 isolate->Throw(*error); 4037 isolate->Throw(*error);
3967 return Handle<Object>(); 4038 return Handle<Object>();
3968 } else { 4039 } else {
3969 return value; 4040 return value;
3970 } 4041 }
3971 } 4042 }
3972 4043
3973 Handle<Object> old_value = isolate->factory()->the_hole_value(); 4044 Handle<Object> old_value = isolate->factory()->the_hole_value();
3974 if (FLAG_harmony_observation && 4045 bool is_observed = FLAG_harmony_observation &&
3975 object->map()->is_observed() && lookup->IsDataProperty()) { 4046 object->map()->is_observed() &&
4047 *name != isolate->heap()->hidden_string();
4048 if (is_observed && lookup->IsDataProperty()) {
3976 old_value = Object::GetProperty(object, name); 4049 old_value = Object::GetProperty(object, name);
3977 } 4050 }
3978 4051
3979 // This is a real property that is not read-only, or it is a 4052 // 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. 4053 // transition or null descriptor and there are no setters in the prototypes.
3981 Handle<Object> result = value; 4054 Handle<Object> result = value;
3982 switch (lookup->type()) { 4055 switch (lookup->type()) {
3983 case NORMAL: 4056 case NORMAL:
3984 SetNormalizedProperty(handle(lookup->holder()), lookup, value); 4057 SetNormalizedProperty(handle(lookup->holder()), lookup, value);
3985 break; 4058 break;
(...skipping 18 matching lines...) Expand all
4004 result = SetPropertyUsingTransition(handle(lookup->holder()), lookup, 4077 result = SetPropertyUsingTransition(handle(lookup->holder()), lookup,
4005 name, value, attributes); 4078 name, value, attributes);
4006 break; 4079 break;
4007 case HANDLER: 4080 case HANDLER:
4008 case NONEXISTENT: 4081 case NONEXISTENT:
4009 UNREACHABLE(); 4082 UNREACHABLE();
4010 } 4083 }
4011 4084
4012 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>()); 4085 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>());
4013 4086
4014 if (FLAG_harmony_observation && object->map()->is_observed()) { 4087 if (is_observed) {
4015 if (lookup->IsTransition()) { 4088 if (lookup->IsTransition()) {
4016 EnqueueChangeRecord(object, "new", name, old_value); 4089 EnqueueChangeRecord(object, "new", name, old_value);
4017 } else { 4090 } else {
4018 LookupResult new_lookup(isolate); 4091 LookupResult new_lookup(isolate);
4019 object->LocalLookup(*name, &new_lookup, true); 4092 object->LocalLookup(*name, &new_lookup, true);
4020 if (new_lookup.IsDataProperty()) { 4093 if (new_lookup.IsDataProperty()) {
4021 Handle<Object> new_value = Object::GetProperty(object, name); 4094 Handle<Object> new_value = Object::GetProperty(object, name);
4022 if (!new_value->SameValue(*old_value)) { 4095 if (!new_value->SameValue(*old_value)) {
4023 EnqueueChangeRecord(object, "updated", name, old_value); 4096 EnqueueChangeRecord(object, "updated", name, old_value);
4024 } 4097 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
4105 4178
4106 // Check for accessor in prototype chain removed here in clone. 4179 // Check for accessor in prototype chain removed here in clone.
4107 if (!lookup.IsFound()) { 4180 if (!lookup.IsFound()) {
4108 // Neither properties nor transitions found. 4181 // Neither properties nor transitions found.
4109 return AddProperty(object, name, value, attributes, kNonStrictMode, 4182 return AddProperty(object, name, value, attributes, kNonStrictMode,
4110 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode); 4183 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode);
4111 } 4184 }
4112 4185
4113 Handle<Object> old_value = isolate->factory()->the_hole_value(); 4186 Handle<Object> old_value = isolate->factory()->the_hole_value();
4114 PropertyAttributes old_attributes = ABSENT; 4187 PropertyAttributes old_attributes = ABSENT;
4115 bool is_observed = FLAG_harmony_observation && object->map()->is_observed(); 4188 bool is_observed = FLAG_harmony_observation &&
4189 object->map()->is_observed() &&
4190 *name != isolate->heap()->hidden_string();
4116 if (is_observed && lookup.IsProperty()) { 4191 if (is_observed && lookup.IsProperty()) {
4117 if (lookup.IsDataProperty()) old_value = 4192 if (lookup.IsDataProperty()) old_value =
4118 Object::GetProperty(object, name); 4193 Object::GetProperty(object, name);
4119 old_attributes = lookup.GetAttributes(); 4194 old_attributes = lookup.GetAttributes();
4120 } 4195 }
4121 4196
4122 // Check of IsReadOnly removed from here in clone. 4197 // Check of IsReadOnly removed from here in clone.
4123 switch (lookup.type()) { 4198 switch (lookup.type()) {
4124 case NORMAL: 4199 case NORMAL:
4125 ReplaceSlowProperty(object, name, value, attributes); 4200 ReplaceSlowProperty(object, name, value, attributes);
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
4391 } 4466 }
4392 if (pt->IsNull()) return ABSENT; 4467 if (pt->IsNull()) return ABSENT;
4393 return JSObject::cast(pt)->GetElementAttributeWithReceiver( 4468 return JSObject::cast(pt)->GetElementAttributeWithReceiver(
4394 receiver, index, true); 4469 receiver, index, true);
4395 } 4470 }
4396 4471
4397 4472
4398 Handle<Map> NormalizedMapCache::Get(Handle<NormalizedMapCache> cache, 4473 Handle<Map> NormalizedMapCache::Get(Handle<NormalizedMapCache> cache,
4399 Handle<JSObject> obj, 4474 Handle<JSObject> obj,
4400 PropertyNormalizationMode mode) { 4475 PropertyNormalizationMode mode) {
4401 Map* fast = obj->map(); 4476 int index = obj->map()->Hash() % kEntries;
4402 int index = fast->Hash() % kEntries; 4477 Handle<Object> result = handle(cache->get(index), cache->GetIsolate());
4403 Object* result = cache->get(index);
4404 if (result->IsMap() && 4478 if (result->IsMap() &&
4405 Map::cast(result)->EquivalentToForNormalization(fast, mode)) { 4479 Handle<Map>::cast(result)->EquivalentToForNormalization(obj->map(),
4480 mode)) {
4406 #ifdef VERIFY_HEAP 4481 #ifdef VERIFY_HEAP
4407 if (FLAG_verify_heap) { 4482 if (FLAG_verify_heap) {
4408 Map::cast(result)->SharedMapVerify(); 4483 Handle<Map>::cast(result)->SharedMapVerify();
4409 } 4484 }
4410 #endif 4485 #endif
4411 #ifdef DEBUG 4486 #ifdef DEBUG
4412 if (FLAG_enable_slow_asserts) { 4487 if (FLAG_enable_slow_asserts) {
4413 // The cached map should match newly created normalized map bit-by-bit, 4488 // 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 4489 // except for the code cache, which can contain some ics which can be
4415 // applied to the shared map. 4490 // applied to the shared map.
4416 Object* fresh; 4491 Handle<Map> fresh = Map::CopyNormalized(handle(obj->map()), mode,
4417 MaybeObject* maybe_fresh = 4492 SHARED_NORMALIZED_MAP);
4418 fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP); 4493
4419 if (maybe_fresh->ToObject(&fresh)) { 4494 ASSERT(memcmp(fresh->address(),
4420 ASSERT(memcmp(Map::cast(fresh)->address(), 4495 Handle<Map>::cast(result)->address(),
4421 Map::cast(result)->address(), 4496 Map::kCodeCacheOffset) == 0);
4422 Map::kCodeCacheOffset) == 0); 4497 STATIC_ASSERT(Map::kDependentCodeOffset ==
4423 STATIC_ASSERT(Map::kDependentCodeOffset == 4498 Map::kCodeCacheOffset + kPointerSize);
4424 Map::kCodeCacheOffset + kPointerSize); 4499 int offset = Map::kDependentCodeOffset + kPointerSize;
4425 int offset = Map::kDependentCodeOffset + kPointerSize; 4500 ASSERT(memcmp(fresh->address() + offset,
4426 ASSERT(memcmp(Map::cast(fresh)->address() + offset, 4501 Handle<Map>::cast(result)->address() + offset,
4427 Map::cast(result)->address() + offset, 4502 Map::kSize - offset) == 0);
4428 Map::kSize - offset) == 0);
4429 }
4430 } 4503 }
4431 #endif 4504 #endif
4432 return handle(Map::cast(result)); 4505 return Handle<Map>::cast(result);
4433 } 4506 }
4434 4507
4435 Isolate* isolate = cache->GetIsolate(); 4508 Isolate* isolate = cache->GetIsolate();
4436 Handle<Map> map = Map::CopyNormalized(handle(fast), mode, 4509 Handle<Map> map = Map::CopyNormalized(handle(obj->map()), mode,
4437 SHARED_NORMALIZED_MAP); 4510 SHARED_NORMALIZED_MAP);
4438 ASSERT(map->is_dictionary_map()); 4511 ASSERT(map->is_dictionary_map());
4439 cache->set(index, *map); 4512 cache->set(index, *map);
4440 isolate->counters()->normalized_maps()->Increment(); 4513 isolate->counters()->normalized_maps()->Increment();
4441 4514
4442 return map; 4515 return map;
4443 } 4516 }
4444 4517
4445 4518
4446 void NormalizedMapCache::Clear() { 4519 void NormalizedMapCache::Clear() {
(...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after
5169 Handle<Object> args[2] = { name, object }; 5242 Handle<Object> args[2] = { name, object };
5170 Handle<Object> error = isolate->factory()->NewTypeError( 5243 Handle<Object> error = isolate->factory()->NewTypeError(
5171 "strict_delete_property", HandleVector(args, ARRAY_SIZE(args))); 5244 "strict_delete_property", HandleVector(args, ARRAY_SIZE(args)));
5172 isolate->Throw(*error); 5245 isolate->Throw(*error);
5173 return Handle<Object>(); 5246 return Handle<Object>();
5174 } 5247 }
5175 return isolate->factory()->false_value(); 5248 return isolate->factory()->false_value();
5176 } 5249 }
5177 5250
5178 Handle<Object> old_value = isolate->factory()->the_hole_value(); 5251 Handle<Object> old_value = isolate->factory()->the_hole_value();
5179 bool is_observed = FLAG_harmony_observation && object->map()->is_observed(); 5252 bool is_observed = FLAG_harmony_observation &&
5253 object->map()->is_observed() &&
5254 *name != isolate->heap()->hidden_string();
5180 if (is_observed && lookup.IsDataProperty()) { 5255 if (is_observed && lookup.IsDataProperty()) {
5181 old_value = Object::GetProperty(object, name); 5256 old_value = Object::GetProperty(object, name);
5182 } 5257 }
5183 Handle<Object> result; 5258 Handle<Object> result;
5184 5259
5185 // Check for interceptor. 5260 // Check for interceptor.
5186 if (lookup.IsInterceptor()) { 5261 if (lookup.IsInterceptor()) {
5187 // Skip interceptor if forcing a deletion. 5262 // Skip interceptor if forcing a deletion.
5188 if (mode == FORCE_DELETION) { 5263 if (mode == FORCE_DELETION) {
5189 result = DeletePropertyPostInterceptor(object, name, mode); 5264 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 5606 // Make sure we never go back to the fast case
5532 dictionary->set_requires_slow_elements(); 5607 dictionary->set_requires_slow_elements();
5533 // Freeze all elements in the dictionary 5608 // Freeze all elements in the dictionary
5534 FreezeDictionary(dictionary); 5609 FreezeDictionary(dictionary);
5535 } 5610 }
5536 5611
5537 return object; 5612 return object;
5538 } 5613 }
5539 5614
5540 5615
5541 MUST_USE_RESULT MaybeObject* JSObject::SetObserved(Isolate* isolate) { 5616 void JSObject::SetObserved(Handle<JSObject> object) {
5542 if (map()->is_observed()) 5617 Isolate* isolate = object->GetIsolate();
5543 return isolate->heap()->undefined_value();
5544 5618
5545 Heap* heap = isolate->heap(); 5619 if (object->map()->is_observed())
5620 return;
5546 5621
5547 if (!HasExternalArrayElements()) { 5622 if (!object->HasExternalArrayElements()) {
5548 // Go to dictionary mode, so that we don't skip map checks. 5623 // Go to dictionary mode, so that we don't skip map checks.
5549 MaybeObject* maybe = NormalizeElements(); 5624 NormalizeElements(object);
5550 if (maybe->IsFailure()) return maybe; 5625 ASSERT(!object->HasFastElements());
5551 ASSERT(!HasFastElements());
5552 } 5626 }
5553 5627
5554 LookupResult result(isolate); 5628 LookupResult result(isolate);
5555 map()->LookupTransition(this, heap->observed_symbol(), &result); 5629 object->map()->LookupTransition(*object,
5630 isolate->heap()->observed_symbol(),
5631 &result);
5556 5632
5557 Map* new_map; 5633 Handle<Map> new_map;
5558 if (result.IsTransition()) { 5634 if (result.IsTransition()) {
5559 new_map = result.GetTransitionTarget(); 5635 new_map = handle(result.GetTransitionTarget());
5560 ASSERT(new_map->is_observed()); 5636 ASSERT(new_map->is_observed());
5561 } else if (map()->CanHaveMoreTransitions()) { 5637 } else if (object->map()->CanHaveMoreTransitions()) {
5562 MaybeObject* maybe_new_map = map()->CopyForObserved(); 5638 new_map = Map::CopyForObserved(handle(object->map()));
5563 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
5564 } else { 5639 } else {
5565 MaybeObject* maybe_copy = map()->Copy(); 5640 new_map = Map::Copy(handle(object->map()));
5566 if (!maybe_copy->To(&new_map)) return maybe_copy;
5567 new_map->set_is_observed(true); 5641 new_map->set_is_observed(true);
5568 } 5642 }
5569 set_map(new_map); 5643 object->set_map(*new_map);
5570
5571 return heap->undefined_value();
5572 } 5644 }
5573 5645
5574 5646
5647 Handle<JSObject> JSObject::Copy(Handle<JSObject> object,
5648 Handle<AllocationSite> site) {
5649 Isolate* isolate = object->GetIsolate();
5650 CALL_HEAP_FUNCTION(isolate,
5651 isolate->heap()->CopyJSObject(*object, *site), JSObject);
5652 }
5653
5654
5575 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) { 5655 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) {
5576 Isolate* isolate = object->GetIsolate(); 5656 Isolate* isolate = object->GetIsolate();
5577 CALL_HEAP_FUNCTION(isolate, 5657 CALL_HEAP_FUNCTION(isolate,
5578 isolate->heap()->CopyJSObject(*object), JSObject); 5658 isolate->heap()->CopyJSObject(*object), JSObject);
5579 } 5659 }
5580 5660
5581 5661
5582 class JSObjectWalkVisitor { 5662 class JSObjectWalkVisitor {
5583 public: 5663 public:
5584 explicit JSObjectWalkVisitor() {} 5664 explicit JSObjectWalkVisitor(AllocationSiteContext* site_context) :
5665 site_context_(site_context) {}
5585 virtual ~JSObjectWalkVisitor() {} 5666 virtual ~JSObjectWalkVisitor() {}
5586 5667
5587 Handle<JSObject> Visit(Handle<JSObject> object) { 5668 Handle<JSObject> Visit(Handle<JSObject> object) {
5588 return StructureWalk(object); 5669 return StructureWalk(object);
5589 } 5670 }
5590 5671
5591 // Returns true if the visitor is a copying visitor.
5592 virtual bool is_copying() = 0; 5672 virtual bool is_copying() = 0;
5593 5673
5594 protected: 5674 protected:
5595 Handle<JSObject> StructureWalk(Handle<JSObject> object); 5675 Handle<JSObject> StructureWalk(Handle<JSObject> object);
5596 5676
5597 // The returned handle should point to a new object if the visitor is a 5677 // 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. 5678 // This allows VisitObject to make a copy of the object if desired.
5599 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) = 0; 5679 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, 5680 virtual Handle<JSObject> VisitElementOrProperty(Handle<JSObject> object,
5604 Handle<JSObject> value) = 0; 5681 Handle<JSObject> value) = 0;
5682
5683 AllocationSiteContext* site_context() { return site_context_; }
5684
5685 private:
5686 AllocationSiteContext* site_context_;
5605 }; 5687 };
5606 5688
5607 5689
5608 class JSObjectCopyVisitor: public JSObjectWalkVisitor { 5690 class JSObjectCopyVisitor: public JSObjectWalkVisitor {
5609 public: 5691 public:
5610 explicit JSObjectCopyVisitor() {} 5692 explicit JSObjectCopyVisitor(AllocationSiteContext* site_context)
5693 : JSObjectWalkVisitor(site_context) {}
5611 5694
5612 virtual bool is_copying() V8_OVERRIDE { return true; } 5695 virtual bool is_copying() V8_OVERRIDE { return true; }
5613 5696
5614 protected: 5697 // The returned handle will be used for the object in all
5698 // subsequent usages. This allows VisitObject to make a copy
5699 // of the object if desired.
5615 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE { 5700 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE {
5616 return JSObject::Copy(object); 5701 // Only create a memento if
5702 // 1) we have a JSArray, and
5703 // 2) the elements kind is palatable
5704 // 3) allow_mementos is true
5705 Handle<JSObject> copy;
5706 if (site_context()->activated() &&
5707 AllocationSite::CanTrack(object->map()->instance_type()) &&
5708 AllocationSite::GetMode(object->GetElementsKind()) ==
5709 TRACK_ALLOCATION_SITE) {
5710 copy = JSObject::Copy(object, site_context()->current());
5711 } else {
5712 copy = JSObject::Copy(object);
5713 }
5714
5715 return copy;
5617 } 5716 }
5618 5717
5619 virtual Handle<JSObject> VisitElementOrProperty( 5718 virtual Handle<JSObject> VisitElementOrProperty(
5620 Handle<JSObject> object, 5719 Handle<JSObject> object,
5621 Handle<JSObject> value) V8_OVERRIDE { 5720 Handle<JSObject> value) V8_OVERRIDE {
5622 return StructureWalk(value); 5721 Handle<AllocationSite> current_site = site_context()->EnterNewScope();
5722 Handle<JSObject> copy_of_value = StructureWalk(value);
5723 site_context()->ExitScope(current_site, value);
5724 return copy_of_value;
5623 } 5725 }
5624 }; 5726 };
5625 5727
5728
5729 class JSObjectCreateAllocationSitesVisitor: public JSObjectWalkVisitor {
5730 public:
5731 explicit JSObjectCreateAllocationSitesVisitor(
5732 AllocationSiteContext* site_context)
5733 : JSObjectWalkVisitor(site_context) {}
5734
5735 virtual bool is_copying() V8_OVERRIDE { return false; }
5736
5737 // The returned handle will be used for the object in all
5738 // subsequent usages. This allows VisitObject to make a copy
5739 // of the object if desired.
5740 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE {
5741 return object;
5742 }
5743
5744 virtual Handle<JSObject> VisitElementOrProperty(
5745 Handle<JSObject> object,
5746 Handle<JSObject> value) V8_OVERRIDE {
5747 Handle<AllocationSite> current_site = site_context()->EnterNewScope();
5748 value = StructureWalk(value);
5749 site_context()->ExitScope(current_site, value);
5750 return value;
5751 }
5752 };
5753
5626 5754
5627 Handle<JSObject> JSObjectWalkVisitor::StructureWalk(Handle<JSObject> object) { 5755 Handle<JSObject> JSObjectWalkVisitor::StructureWalk(Handle<JSObject> object) {
5628 bool copying = is_copying(); 5756 bool copying = is_copying();
5629 Isolate* isolate = object->GetIsolate(); 5757 Isolate* isolate = object->GetIsolate();
5630 StackLimitCheck check(isolate); 5758 StackLimitCheck check(isolate);
5631 if (check.HasOverflowed()) { 5759 if (check.HasOverflowed()) {
5632 isolate->StackOverflow(); 5760 isolate->StackOverflow();
5633 return Handle<JSObject>::null(); 5761 return Handle<JSObject>::null();
5634 } 5762 }
5635 5763
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
5759 case EXTERNAL_DOUBLE_ELEMENTS: 5887 case EXTERNAL_DOUBLE_ELEMENTS:
5760 case FAST_DOUBLE_ELEMENTS: 5888 case FAST_DOUBLE_ELEMENTS:
5761 case FAST_HOLEY_DOUBLE_ELEMENTS: 5889 case FAST_HOLEY_DOUBLE_ELEMENTS:
5762 // No contained objects, nothing to do. 5890 // No contained objects, nothing to do.
5763 break; 5891 break;
5764 } 5892 }
5765 return copy; 5893 return copy;
5766 } 5894 }
5767 5895
5768 5896
5769 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) { 5897 Handle<JSObject> JSObject::DeepWalk(Handle<JSObject> object,
5770 JSObjectCopyVisitor v; 5898 AllocationSiteContext* site_context) {
5899 JSObjectCreateAllocationSitesVisitor v(site_context);
5900 Handle<JSObject> result = v.Visit(object);
5901 ASSERT(!v.is_copying() &&
5902 (result.is_null() || result.is_identical_to(object)));
5903 return result;
5904 }
5905
5906
5907 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object,
5908 AllocationSiteContext* site_context) {
5909 JSObjectCopyVisitor v(site_context);
5771 Handle<JSObject> copy = v.Visit(object); 5910 Handle<JSObject> copy = v.Visit(object);
5772 ASSERT(v.is_copying() && !copy.is_identical_to(object)); 5911 ASSERT(v.is_copying() && !copy.is_identical_to(object));
5773 return copy; 5912 return copy;
5774 } 5913 }
5775 5914
5776 5915
5777 // Tests for the fast common case for property enumeration: 5916 // Tests for the fast common case for property enumeration:
5778 // - This object and all prototypes has an enum cache (which means that 5917 // - 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). 5918 // it is no proxy, has no interceptors and needs no access checks).
5780 // - This object has no elements. 5919 // - This object has no elements.
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
6177 6316
6178 // Try to flatten before operating on the string. 6317 // Try to flatten before operating on the string.
6179 if (name->IsString()) String::cast(*name)->TryFlatten(); 6318 if (name->IsString()) String::cast(*name)->TryFlatten();
6180 6319
6181 if (!object->CanSetCallback(*name)) return; 6320 if (!object->CanSetCallback(*name)) return;
6182 6321
6183 uint32_t index = 0; 6322 uint32_t index = 0;
6184 bool is_element = name->AsArrayIndex(&index); 6323 bool is_element = name->AsArrayIndex(&index);
6185 6324
6186 Handle<Object> old_value = isolate->factory()->the_hole_value(); 6325 Handle<Object> old_value = isolate->factory()->the_hole_value();
6187 bool is_observed = FLAG_harmony_observation && object->map()->is_observed(); 6326 bool is_observed = FLAG_harmony_observation &&
6327 object->map()->is_observed() &&
6328 *name != isolate->heap()->hidden_string();
6188 bool preexists = false; 6329 bool preexists = false;
6189 if (is_observed) { 6330 if (is_observed) {
6190 if (is_element) { 6331 if (is_element) {
6191 preexists = HasLocalElement(object, index); 6332 preexists = HasLocalElement(object, index);
6192 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) { 6333 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) {
6193 old_value = Object::GetElement(isolate, object, index); 6334 old_value = Object::GetElement(isolate, object, index);
6194 } 6335 }
6195 } else { 6336 } else {
6196 LookupResult lookup(isolate); 6337 LookupResult lookup(isolate);
6197 object->LocalLookup(*name, &lookup, true); 6338 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)) { 6573 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_HAS)) {
6433 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS); 6574 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS);
6434 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); 6575 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
6435 return isolate->factory()->undefined_value(); 6576 return isolate->factory()->undefined_value();
6436 } 6577 }
6437 6578
6438 // Make the lookup and include prototypes. 6579 // Make the lookup and include prototypes.
6439 uint32_t index = 0; 6580 uint32_t index = 0;
6440 if (name->AsArrayIndex(&index)) { 6581 if (name->AsArrayIndex(&index)) {
6441 for (Handle<Object> obj = object; 6582 for (Handle<Object> obj = object;
6442 *obj != isolate->heap()->null_value(); 6583 !obj->IsNull();
6443 obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) { 6584 obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) {
6444 if (obj->IsJSObject() && JSObject::cast(*obj)->HasDictionaryElements()) { 6585 if (obj->IsJSObject() && JSObject::cast(*obj)->HasDictionaryElements()) {
6445 JSObject* js_object = JSObject::cast(*obj); 6586 JSObject* js_object = JSObject::cast(*obj);
6446 SeededNumberDictionary* dictionary = js_object->element_dictionary(); 6587 SeededNumberDictionary* dictionary = js_object->element_dictionary();
6447 int entry = dictionary->FindEntry(index); 6588 int entry = dictionary->FindEntry(index);
6448 if (entry != SeededNumberDictionary::kNotFound) { 6589 if (entry != SeededNumberDictionary::kNotFound) {
6449 Object* element = dictionary->ValueAt(entry); 6590 Object* element = dictionary->ValueAt(entry);
6450 if (dictionary->DetailsAt(entry).type() == CALLBACKS && 6591 if (dictionary->DetailsAt(entry).type() == CALLBACKS &&
6451 element->IsAccessorPair()) { 6592 element->IsAccessorPair()) {
6452 return handle(AccessorPair::cast(element)->GetComponent(component), 6593 return handle(AccessorPair::cast(element)->GetComponent(component),
6453 isolate); 6594 isolate);
6454 } 6595 }
6455 } 6596 }
6456 } 6597 }
6457 } 6598 }
6458 } else { 6599 } else {
6459 for (Handle<Object> obj = object; 6600 for (Handle<Object> obj = object;
6460 *obj != isolate->heap()->null_value(); 6601 !obj->IsNull();
6461 obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) { 6602 obj = handle(JSReceiver::cast(*obj)->GetPrototype(), isolate)) {
6462 LookupResult result(isolate); 6603 LookupResult result(isolate);
6463 JSReceiver::cast(*obj)->LocalLookup(*name, &result); 6604 JSReceiver::cast(*obj)->LocalLookup(*name, &result);
6464 if (result.IsFound()) { 6605 if (result.IsFound()) {
6465 if (result.IsReadOnly()) return isolate->factory()->undefined_value(); 6606 if (result.IsReadOnly()) return isolate->factory()->undefined_value();
6466 if (result.IsPropertyCallbacks()) { 6607 if (result.IsPropertyCallbacks()) {
6467 Object* obj = result.GetCallbackObject(); 6608 Object* obj = result.GetCallbackObject();
6468 if (obj->IsAccessorPair()) { 6609 if (obj->IsAccessorPair()) {
6469 return handle(AccessorPair::cast(obj)->GetComponent(component), 6610 return handle(AccessorPair::cast(obj)->GetComponent(component),
6470 isolate); 6611 isolate);
(...skipping 28 matching lines...) Expand all
6499 } 6640 }
6500 } 6641 }
6501 } 6642 }
6502 return GetHeap()->undefined_value(); 6643 return GetHeap()->undefined_value();
6503 } else { 6644 } else {
6504 return property_dictionary()->SlowReverseLookup(value); 6645 return property_dictionary()->SlowReverseLookup(value);
6505 } 6646 }
6506 } 6647 }
6507 6648
6508 6649
6650 Handle<Map> Map::RawCopy(Handle<Map> map,
6651 int instance_size) {
6652 CALL_HEAP_FUNCTION(map->GetIsolate(),
6653 map->RawCopy(instance_size),
6654 Map);
6655 }
6656
6657
6509 MaybeObject* Map::RawCopy(int instance_size) { 6658 MaybeObject* Map::RawCopy(int instance_size) {
6510 Map* result; 6659 Map* result;
6511 MaybeObject* maybe_result = 6660 MaybeObject* maybe_result =
6512 GetHeap()->AllocateMap(instance_type(), instance_size); 6661 GetHeap()->AllocateMap(instance_type(), instance_size);
6513 if (!maybe_result->To(&result)) return maybe_result; 6662 if (!maybe_result->To(&result)) return maybe_result;
6514 6663
6515 result->set_prototype(prototype()); 6664 result->set_prototype(prototype());
6516 result->set_constructor(constructor()); 6665 result->set_constructor(constructor());
6517 result->set_bit_field(bit_field()); 6666 result->set_bit_field(bit_field());
6518 result->set_bit_field2(bit_field2()); 6667 result->set_bit_field2(bit_field2());
6519 int new_bit_field3 = bit_field3(); 6668 int new_bit_field3 = bit_field3();
6520 new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true); 6669 new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true);
6521 new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0); 6670 new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0);
6522 new_bit_field3 = EnumLengthBits::update(new_bit_field3, kInvalidEnumCache); 6671 new_bit_field3 = EnumLengthBits::update(new_bit_field3, kInvalidEnumCache);
6523 new_bit_field3 = Deprecated::update(new_bit_field3, false); 6672 new_bit_field3 = Deprecated::update(new_bit_field3, false);
6524 new_bit_field3 = IsUnstable::update(new_bit_field3, false); 6673 new_bit_field3 = IsUnstable::update(new_bit_field3, false);
6525 result->set_bit_field3(new_bit_field3); 6674 result->set_bit_field3(new_bit_field3);
6526 return result; 6675 return result;
6527 } 6676 }
6528 6677
6529 6678
6530 Handle<Map> Map::CopyNormalized(Handle<Map> map, 6679 Handle<Map> Map::CopyNormalized(Handle<Map> map,
6531 PropertyNormalizationMode mode, 6680 PropertyNormalizationMode mode,
6532 NormalizedMapSharingMode sharing) { 6681 NormalizedMapSharingMode sharing) {
6533 CALL_HEAP_FUNCTION(map->GetIsolate(), 6682 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) { 6683 if (mode == CLEAR_INOBJECT_PROPERTIES) {
6543 new_instance_size -= inobject_properties() * kPointerSize; 6684 new_instance_size -= map->inobject_properties() * kPointerSize;
6544 } 6685 }
6545 6686
6546 Map* result; 6687 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 6688
6550 if (mode != CLEAR_INOBJECT_PROPERTIES) { 6689 if (mode != CLEAR_INOBJECT_PROPERTIES) {
6551 result->set_inobject_properties(inobject_properties()); 6690 result->set_inobject_properties(map->inobject_properties());
6552 } 6691 }
6553 6692
6554 result->set_is_shared(sharing == SHARED_NORMALIZED_MAP); 6693 result->set_is_shared(sharing == SHARED_NORMALIZED_MAP);
6555 result->set_dictionary_map(true); 6694 result->set_dictionary_map(true);
6556 result->set_migration_target(false); 6695 result->set_migration_target(false);
6557 6696
6558 #ifdef VERIFY_HEAP 6697 #ifdef VERIFY_HEAP
6559 if (FLAG_verify_heap && result->is_shared()) { 6698 if (FLAG_verify_heap && result->is_shared()) {
6560 result->SharedMapVerify(); 6699 result->SharedMapVerify();
6561 } 6700 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
6691 set_transitions(transitions); 6830 set_transitions(transitions);
6692 result->SetBackPointer(this); 6831 result->SetBackPointer(this);
6693 } else { 6832 } else {
6694 descriptors->InitializeRepresentations(Representation::Tagged()); 6833 descriptors->InitializeRepresentations(Representation::Tagged());
6695 } 6834 }
6696 6835
6697 return result; 6836 return result;
6698 } 6837 }
6699 6838
6700 6839
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 6840 // Since this method is used to rewrite an existing transition tree, it can
6711 // always insert transitions without checking. 6841 // always insert transitions without checking.
6712 MaybeObject* Map::CopyInstallDescriptors(int new_descriptor, 6842 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map,
6713 DescriptorArray* descriptors) { 6843 int new_descriptor,
6844 Handle<DescriptorArray> descriptors) {
6714 ASSERT(descriptors->IsSortedNoDuplicates()); 6845 ASSERT(descriptors->IsSortedNoDuplicates());
6715 6846
6716 Map* result; 6847 Handle<Map> result = Map::CopyDropDescriptors(map);
6717 MaybeObject* maybe_result = CopyDropDescriptors();
6718 if (!maybe_result->To(&result)) return maybe_result;
6719 6848
6720 result->InitializeDescriptors(descriptors); 6849 result->InitializeDescriptors(*descriptors);
6721 result->SetNumberOfOwnDescriptors(new_descriptor + 1); 6850 result->SetNumberOfOwnDescriptors(new_descriptor + 1);
6722 6851
6723 int unused_property_fields = this->unused_property_fields(); 6852 int unused_property_fields = map->unused_property_fields();
6724 if (descriptors->GetDetails(new_descriptor).type() == FIELD) { 6853 if (descriptors->GetDetails(new_descriptor).type() == FIELD) {
6725 unused_property_fields = this->unused_property_fields() - 1; 6854 unused_property_fields = map->unused_property_fields() - 1;
6726 if (unused_property_fields < 0) { 6855 if (unused_property_fields < 0) {
6727 unused_property_fields += JSObject::kFieldsAdded; 6856 unused_property_fields += JSObject::kFieldsAdded;
6728 } 6857 }
6729 } 6858 }
6730 6859
6731 result->set_unused_property_fields(unused_property_fields); 6860 result->set_unused_property_fields(unused_property_fields);
6732 result->set_owns_descriptors(false); 6861 result->set_owns_descriptors(false);
6733 6862
6734 Name* name = descriptors->GetKey(new_descriptor); 6863 Handle<Name> name = handle(descriptors->GetKey(new_descriptor));
6735 TransitionArray* transitions; 6864 Handle<TransitionArray> transitions = Map::AddTransition(map, name, result,
6736 MaybeObject* maybe_transitions = 6865 SIMPLE_TRANSITION);
6737 AddTransition(name, result, SIMPLE_TRANSITION);
6738 if (!maybe_transitions->To(&transitions)) return maybe_transitions;
6739 6866
6740 set_transitions(transitions); 6867 map->set_transitions(*transitions);
6741 result->SetBackPointer(this); 6868 result->SetBackPointer(*map);
6742 6869
6743 return result; 6870 return result;
6744 } 6871 }
6745 6872
6746 6873
6747 MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) { 6874 MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) {
6748 if (flag == INSERT_TRANSITION) { 6875 if (flag == INSERT_TRANSITION) {
6749 ASSERT(!HasElementsTransition() || 6876 ASSERT(!HasElementsTransition() ||
6750 ((elements_transition_map()->elements_kind() == DICTIONARY_ELEMENTS || 6877 ((elements_transition_map()->elements_kind() == DICTIONARY_ELEMENTS ||
6751 IsExternalArrayElementsKind( 6878 IsExternalArrayElementsKind(
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
6789 if (insert_transition) { 6916 if (insert_transition) {
6790 MaybeObject* added_elements = set_elements_transition_map(new_map); 6917 MaybeObject* added_elements = set_elements_transition_map(new_map);
6791 if (added_elements->IsFailure()) return added_elements; 6918 if (added_elements->IsFailure()) return added_elements;
6792 new_map->SetBackPointer(this); 6919 new_map->SetBackPointer(this);
6793 } 6920 }
6794 6921
6795 return new_map; 6922 return new_map;
6796 } 6923 }
6797 6924
6798 6925
6799 MaybeObject* Map::CopyForObserved() { 6926 Handle<Map> Map::CopyForObserved(Handle<Map> map) {
6800 ASSERT(!is_observed()); 6927 ASSERT(!map->is_observed());
6928
6929 Isolate* isolate = map->GetIsolate();
6801 6930
6802 // In case the map owned its own descriptors, share the descriptors and 6931 // In case the map owned its own descriptors, share the descriptors and
6803 // transfer ownership to the new map. 6932 // transfer ownership to the new map.
6804 Map* new_map; 6933 Handle<Map> new_map;
6805 MaybeObject* maybe_new_map; 6934 if (map->owns_descriptors()) {
6806 if (owns_descriptors()) { 6935 new_map = Map::CopyDropDescriptors(map);
6807 maybe_new_map = CopyDropDescriptors();
6808 } else { 6936 } else {
6809 maybe_new_map = Copy(); 6937 new_map = Map::Copy(map);
6810 } 6938 }
6811 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
6812 6939
6813 TransitionArray* transitions; 6940 Handle<TransitionArray> transitions =
6814 MaybeObject* maybe_transitions = AddTransition(GetHeap()->observed_symbol(), 6941 Map::AddTransition(map, isolate->factory()->observed_symbol(), new_map,
6815 new_map, 6942 FULL_TRANSITION);
6816 FULL_TRANSITION); 6943
6817 if (!maybe_transitions->To(&transitions)) return maybe_transitions; 6944 map->set_transitions(*transitions);
6818 set_transitions(transitions);
6819 6945
6820 new_map->set_is_observed(true); 6946 new_map->set_is_observed(true);
6821 6947
6822 if (owns_descriptors()) { 6948 if (map->owns_descriptors()) {
6823 new_map->InitializeDescriptors(instance_descriptors()); 6949 new_map->InitializeDescriptors(map->instance_descriptors());
6824 set_owns_descriptors(false); 6950 map->set_owns_descriptors(false);
6825 } 6951 }
6826 6952
6827 new_map->SetBackPointer(this); 6953 new_map->SetBackPointer(*map);
6828 return new_map; 6954 return new_map;
6829 } 6955 }
6830 6956
6831 6957
6832 MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() { 6958 MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() {
6833 if (pre_allocated_property_fields() == 0) return CopyDropDescriptors(); 6959 if (pre_allocated_property_fields() == 0) return CopyDropDescriptors();
6834 6960
6835 // If the map has pre-allocated properties always start out with a descriptor 6961 // If the map has pre-allocated properties always start out with a descriptor
6836 // array describing these properties. 6962 // array describing these properties.
6837 ASSERT(constructor()->IsJSFunction()); 6963 ASSERT(constructor()->IsJSFunction());
(...skipping 2421 matching lines...) Expand 10 before | Expand all | Expand 10 after
9259 // TODO(verwaest) Should be an assert, otherwise back pointers are not 9385 // TODO(verwaest) Should be an assert, otherwise back pointers are not
9260 // properly cleared. 9386 // properly cleared.
9261 if (transition_index == t->number_of_transitions()) return; 9387 if (transition_index == t->number_of_transitions()) return;
9262 9388
9263 int number_of_own_descriptors = NumberOfOwnDescriptors(); 9389 int number_of_own_descriptors = NumberOfOwnDescriptors();
9264 9390
9265 if (descriptors_owner_died) { 9391 if (descriptors_owner_died) {
9266 if (number_of_own_descriptors > 0) { 9392 if (number_of_own_descriptors > 0) {
9267 TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors); 9393 TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors);
9268 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors); 9394 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors);
9395 set_owns_descriptors(true);
9269 } else { 9396 } else {
9270 ASSERT(descriptors == GetHeap()->empty_descriptor_array()); 9397 ASSERT(descriptors == GetHeap()->empty_descriptor_array());
9271 } 9398 }
9272 } 9399 }
9273 9400
9274 int trim = t->number_of_transitions() - transition_index; 9401 int trim = t->number_of_transitions() - transition_index;
9275 if (trim > 0) { 9402 if (trim > 0) {
9276 RightTrimFixedArray<FROM_GC>(heap, t, t->IsSimpleTransition() 9403 RightTrimFixedArray<FROM_GC>(heap, t, t->IsSimpleTransition()
9277 ? trim : trim * TransitionArray::kTransitionSize); 9404 ? trim : trim * TransitionArray::kTransitionSize);
9278 } 9405 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
9315 9442
9316 9443
9317 bool Map::EquivalentToForNormalization(Map* other, 9444 bool Map::EquivalentToForNormalization(Map* other,
9318 PropertyNormalizationMode mode) { 9445 PropertyNormalizationMode mode) {
9319 int properties = mode == CLEAR_INOBJECT_PROPERTIES 9446 int properties = mode == CLEAR_INOBJECT_PROPERTIES
9320 ? 0 : other->inobject_properties(); 9447 ? 0 : other->inobject_properties();
9321 return CheckEquivalent(this, other) && inobject_properties() == properties; 9448 return CheckEquivalent(this, other) && inobject_properties() == properties;
9322 } 9449 }
9323 9450
9324 9451
9452 void ConstantPoolArray::ConstantPoolIterateBody(ObjectVisitor* v) {
9453 int first_ptr_offset = OffsetOfElementAt(first_ptr_index());
9454 int last_ptr_offset =
9455 OffsetOfElementAt(first_ptr_index() + count_of_ptr_entries());
9456 v->VisitPointers(
9457 HeapObject::RawField(this, first_ptr_offset),
9458 HeapObject::RawField(this, last_ptr_offset));
9459 }
9460
9461
9325 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) { 9462 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) {
9326 // Iterate over all fields in the body but take care in dealing with 9463 // Iterate over all fields in the body but take care in dealing with
9327 // the code entry. 9464 // the code entry.
9328 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset); 9465 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset);
9329 v->VisitCodeEntry(this->address() + kCodeEntryOffset); 9466 v->VisitCodeEntry(this->address() + kCodeEntryOffset);
9330 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size); 9467 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size);
9331 } 9468 }
9332 9469
9333 9470
9334 void JSFunction::MarkForLazyRecompilation() { 9471 void JSFunction::MarkForLazyRecompilation() {
(...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after
10167 10304
10168 10305
10169 void ObjectVisitor::VisitEmbeddedPointer(RelocInfo* rinfo) { 10306 void ObjectVisitor::VisitEmbeddedPointer(RelocInfo* rinfo) {
10170 ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); 10307 ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
10171 VisitPointer(rinfo->target_object_address()); 10308 VisitPointer(rinfo->target_object_address());
10172 } 10309 }
10173 10310
10174 10311
10175 void ObjectVisitor::VisitExternalReference(RelocInfo* rinfo) { 10312 void ObjectVisitor::VisitExternalReference(RelocInfo* rinfo) {
10176 Address* p = rinfo->target_reference_address(); 10313 Address* p = rinfo->target_reference_address();
10177 VisitExternalReferences(p, p + 1); 10314 VisitExternalReference(p);
10178 } 10315 }
10179 10316
10180 10317
10181 void Code::InvalidateRelocation() { 10318 void Code::InvalidateRelocation() {
10182 set_relocation_info(GetHeap()->empty_byte_array()); 10319 set_relocation_info(GetHeap()->empty_byte_array());
10183 } 10320 }
10184 10321
10185 10322
10186 void Code::Relocate(intptr_t delta) { 10323 void Code::Relocate(intptr_t delta) {
10187 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { 10324 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)) { 10361 } else if (RelocInfo::IsCodeTarget(mode)) {
10225 // rewrite code handles in inline cache targets to direct 10362 // rewrite code handles in inline cache targets to direct
10226 // pointers to the first instruction in the code object 10363 // pointers to the first instruction in the code object
10227 Handle<Object> p = it.rinfo()->target_object_handle(origin); 10364 Handle<Object> p = it.rinfo()->target_object_handle(origin);
10228 Code* code = Code::cast(*p); 10365 Code* code = Code::cast(*p);
10229 it.rinfo()->set_target_address(code->instruction_start(), 10366 it.rinfo()->set_target_address(code->instruction_start(),
10230 SKIP_WRITE_BARRIER); 10367 SKIP_WRITE_BARRIER);
10231 } else if (RelocInfo::IsRuntimeEntry(mode)) { 10368 } else if (RelocInfo::IsRuntimeEntry(mode)) {
10232 Address p = it.rinfo()->target_runtime_entry(origin); 10369 Address p = it.rinfo()->target_runtime_entry(origin);
10233 it.rinfo()->set_target_runtime_entry(p, SKIP_WRITE_BARRIER); 10370 it.rinfo()->set_target_runtime_entry(p, SKIP_WRITE_BARRIER);
10371 } else if (mode == RelocInfo::CODE_AGE_SEQUENCE) {
10372 Handle<Object> p = it.rinfo()->code_age_stub_handle(origin);
10373 Code* code = Code::cast(*p);
10374 it.rinfo()->set_code_age_stub(code);
10234 } else { 10375 } else {
10235 it.rinfo()->apply(delta); 10376 it.rinfo()->apply(delta);
10236 } 10377 }
10237 } 10378 }
10238 CPU::FlushICache(instruction_start(), instruction_size()); 10379 CPU::FlushICache(instruction_start(), instruction_size());
10239 } 10380 }
10240 10381
10241 10382
10242 // Locate the source position which is closest to the address in the code. This 10383 // 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. 10384 // 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); 10602 ASSERT(kind() == FUNCTION);
10462 BackEdgeTable back_edges(this, &no_gc); 10603 BackEdgeTable back_edges(this, &no_gc);
10463 for (uint32_t i = 0; i < back_edges.length(); i++) { 10604 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); 10605 if (back_edges.pc_offset(i) == pc_offset) return back_edges.ast_id(i);
10465 } 10606 }
10466 return BailoutId::None(); 10607 return BailoutId::None();
10467 } 10608 }
10468 10609
10469 10610
10470 void Code::MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate) { 10611 void Code::MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate) {
10471 PatchPlatformCodeAge(isolate, sequence, kNoAge, NO_MARKING_PARITY); 10612 PatchPlatformCodeAge(isolate, sequence, kNoAgeCodeAge, NO_MARKING_PARITY);
10472 } 10613 }
10473 10614
10474 10615
10616 void Code::MarkCodeAsExecuted(byte* sequence, Isolate* isolate) {
10617 PatchPlatformCodeAge(isolate, sequence, kExecutedOnceCodeAge,
10618 NO_MARKING_PARITY);
10619 }
10620
10621
10475 void Code::MakeOlder(MarkingParity current_parity) { 10622 void Code::MakeOlder(MarkingParity current_parity) {
10476 byte* sequence = FindCodeAgeSequence(); 10623 byte* sequence = FindCodeAgeSequence();
10477 if (sequence != NULL) { 10624 if (sequence != NULL) {
10478 Age age; 10625 Age age;
10479 MarkingParity code_parity; 10626 MarkingParity code_parity;
10480 GetCodeAgeAndParity(sequence, &age, &code_parity); 10627 GetCodeAgeAndParity(sequence, &age, &code_parity);
10481 if (age != kLastCodeAge && code_parity != current_parity) { 10628 if (age != kLastCodeAge && code_parity != current_parity) {
10482 PatchPlatformCodeAge(GetIsolate(), 10629 PatchPlatformCodeAge(GetIsolate(),
10483 sequence, 10630 sequence,
10484 static_cast<Age>(age + 1), 10631 static_cast<Age>(age + 1),
10485 current_parity); 10632 current_parity);
10486 } 10633 }
10487 } 10634 }
10488 } 10635 }
10489 10636
10490 10637
10491 bool Code::IsOld() { 10638 bool Code::IsOld() {
10492 byte* sequence = FindCodeAgeSequence(); 10639 Age age = GetAge();
10493 if (sequence == NULL) return false; 10640 return age >= kIsOldCodeAge;
10494 Age age;
10495 MarkingParity parity;
10496 GetCodeAgeAndParity(sequence, &age, &parity);
10497 return age >= kSexagenarianCodeAge;
10498 } 10641 }
10499 10642
10500 10643
10501 byte* Code::FindCodeAgeSequence() { 10644 byte* Code::FindCodeAgeSequence() {
10502 return FLAG_age_code && 10645 return FLAG_age_code &&
10503 prologue_offset() != kPrologueOffsetNotSet && 10646 prologue_offset() != Code::kPrologueOffsetNotSet &&
10504 (kind() == OPTIMIZED_FUNCTION || 10647 (kind() == OPTIMIZED_FUNCTION ||
10505 (kind() == FUNCTION && !has_debug_break_slots())) 10648 (kind() == FUNCTION && !has_debug_break_slots()))
10506 ? instruction_start() + prologue_offset() 10649 ? instruction_start() + prologue_offset()
10507 : NULL; 10650 : NULL;
10508 } 10651 }
10509 10652
10510 10653
10511 int Code::GetAge() { 10654 Code::Age Code::GetAge() {
10512 byte* sequence = FindCodeAgeSequence(); 10655 byte* sequence = FindCodeAgeSequence();
10513 if (sequence == NULL) { 10656 if (sequence == NULL) {
10514 return Code::kNoAge; 10657 return Code::kNoAgeCodeAge;
10515 } 10658 }
10516 Age age; 10659 Age age;
10517 MarkingParity parity; 10660 MarkingParity parity;
10518 GetCodeAgeAndParity(sequence, &age, &parity); 10661 GetCodeAgeAndParity(sequence, &age, &parity);
10519 return age; 10662 return age;
10520 } 10663 }
10521 10664
10522 10665
10523 void Code::GetCodeAgeAndParity(Code* code, Age* age, 10666 void Code::GetCodeAgeAndParity(Code* code, Age* age,
10524 MarkingParity* parity) { 10667 MarkingParity* parity) {
10525 Isolate* isolate = code->GetIsolate(); 10668 Isolate* isolate = code->GetIsolate();
10526 Builtins* builtins = isolate->builtins(); 10669 Builtins* builtins = isolate->builtins();
10527 Code* stub = NULL; 10670 Code* stub = NULL;
10528 #define HANDLE_CODE_AGE(AGE) \ 10671 #define HANDLE_CODE_AGE(AGE) \
10529 stub = *builtins->Make##AGE##CodeYoungAgainEvenMarking(); \ 10672 stub = *builtins->Make##AGE##CodeYoungAgainEvenMarking(); \
10530 if (code == stub) { \ 10673 if (code == stub) { \
10531 *age = k##AGE##CodeAge; \ 10674 *age = k##AGE##CodeAge; \
10532 *parity = EVEN_MARKING_PARITY; \ 10675 *parity = EVEN_MARKING_PARITY; \
10533 return; \ 10676 return; \
10534 } \ 10677 } \
10535 stub = *builtins->Make##AGE##CodeYoungAgainOddMarking(); \ 10678 stub = *builtins->Make##AGE##CodeYoungAgainOddMarking(); \
10536 if (code == stub) { \ 10679 if (code == stub) { \
10537 *age = k##AGE##CodeAge; \ 10680 *age = k##AGE##CodeAge; \
10538 *parity = ODD_MARKING_PARITY; \ 10681 *parity = ODD_MARKING_PARITY; \
10539 return; \ 10682 return; \
10540 } 10683 }
10541 CODE_AGE_LIST(HANDLE_CODE_AGE) 10684 CODE_AGE_LIST(HANDLE_CODE_AGE)
10542 #undef HANDLE_CODE_AGE 10685 #undef HANDLE_CODE_AGE
10686 stub = *builtins->MarkCodeAsExecutedOnce();
10687 if (code == stub) {
10688 // Treat that's never been executed as old immediatly.
10689 *age = kIsOldCodeAge;
10690 *parity = NO_MARKING_PARITY;
10691 return;
10692 }
10693 stub = *builtins->MarkCodeAsExecutedTwice();
10694 if (code == stub) {
10695 // Pre-age code that has only been executed once.
10696 *age = kPreAgedCodeAge;
10697 *parity = NO_MARKING_PARITY;
10698 return;
10699 }
10543 UNREACHABLE(); 10700 UNREACHABLE();
10544 } 10701 }
10545 10702
10546 10703
10547 Code* Code::GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity) { 10704 Code* Code::GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity) {
10548 Builtins* builtins = isolate->builtins(); 10705 Builtins* builtins = isolate->builtins();
10549 switch (age) { 10706 switch (age) {
10550 #define HANDLE_CODE_AGE(AGE) \ 10707 #define HANDLE_CODE_AGE(AGE) \
10551 case k##AGE##CodeAge: { \ 10708 case k##AGE##CodeAge: { \
10552 Code* stub = parity == EVEN_MARKING_PARITY \ 10709 Code* stub = parity == EVEN_MARKING_PARITY \
10553 ? *builtins->Make##AGE##CodeYoungAgainEvenMarking() \ 10710 ? *builtins->Make##AGE##CodeYoungAgainEvenMarking() \
10554 : *builtins->Make##AGE##CodeYoungAgainOddMarking(); \ 10711 : *builtins->Make##AGE##CodeYoungAgainOddMarking(); \
10555 return stub; \ 10712 return stub; \
10556 } 10713 }
10557 CODE_AGE_LIST(HANDLE_CODE_AGE) 10714 CODE_AGE_LIST(HANDLE_CODE_AGE)
10558 #undef HANDLE_CODE_AGE 10715 #undef HANDLE_CODE_AGE
10716 case kNotExecutedCodeAge: {
10717 ASSERT(parity == NO_MARKING_PARITY);
10718 return *builtins->MarkCodeAsExecutedOnce();
10719 }
10720 case kExecutedOnceCodeAge: {
10721 ASSERT(parity == NO_MARKING_PARITY);
10722 return *builtins->MarkCodeAsExecutedTwice();
10723 }
10559 default: 10724 default:
10560 UNREACHABLE(); 10725 UNREACHABLE();
10561 break; 10726 break;
10562 } 10727 }
10563 return NULL; 10728 return NULL;
10564 } 10729 }
10565 10730
10566 10731
10567 void Code::PrintDeoptLocation(int bailout_id) { 10732 void Code::PrintDeoptLocation(int bailout_id) {
10568 const char* last_comment = NULL; 10733 const char* last_comment = NULL;
(...skipping 1944 matching lines...) Expand 10 before | Expand all | Expand 10 after
12513 } 12678 }
12514 12679
12515 12680
12516 void JSObject::TransitionElementsKind(Handle<JSObject> object, 12681 void JSObject::TransitionElementsKind(Handle<JSObject> object,
12517 ElementsKind to_kind) { 12682 ElementsKind to_kind) {
12518 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), 12683 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(),
12519 object->TransitionElementsKind(to_kind)); 12684 object->TransitionElementsKind(to_kind));
12520 } 12685 }
12521 12686
12522 12687
12688 bool AllocationSite::IsNestedSite() {
12689 ASSERT(FLAG_trace_track_allocation_sites);
12690 Object* current = GetHeap()->allocation_sites_list();
12691 while (current != NULL && current->IsAllocationSite()) {
12692 AllocationSite* current_site = AllocationSite::cast(current);
12693 if (current_site->nested_site() == this) {
12694 return true;
12695 }
12696 current = current_site->weak_next();
12697 }
12698 return false;
12699 }
12700
12701
12523 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) { 12702 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) {
12524 if (!FLAG_track_allocation_sites || !IsJSArray()) { 12703 if (!FLAG_track_allocation_sites || !IsJSArray()) {
12525 return this; 12704 return this;
12526 } 12705 }
12527 12706
12528 AllocationMemento* memento = AllocationMemento::FindForJSObject(this); 12707 AllocationMemento* memento = AllocationMemento::FindForJSObject(this);
12529 if (memento == NULL || !memento->IsValid()) { 12708 if (memento == NULL || !memento->IsValid()) {
12530 return this; 12709 return this;
12531 } 12710 }
12532 12711
12533 // Walk through to the Allocation Site 12712 // Walk through to the Allocation Site
12534 AllocationSite* site = memento->GetAllocationSite(); 12713 AllocationSite* site = memento->GetAllocationSite();
12535 if (site->IsLiteralSite()) { 12714 if (site->SitePointsToLiteral() &&
12715 site->transition_info()->IsJSArray()) {
12536 JSArray* transition_info = JSArray::cast(site->transition_info()); 12716 JSArray* transition_info = JSArray::cast(site->transition_info());
12537 ElementsKind kind = transition_info->GetElementsKind(); 12717 ElementsKind kind = transition_info->GetElementsKind();
12538 // if kind is holey ensure that to_kind is as well. 12718 // if kind is holey ensure that to_kind is as well.
12539 if (IsHoleyElementsKind(kind)) { 12719 if (IsHoleyElementsKind(kind)) {
12540 to_kind = GetHoleyElementsKind(to_kind); 12720 to_kind = GetHoleyElementsKind(to_kind);
12541 } 12721 }
12542 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { 12722 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
12543 // If the array is huge, it's not likely to be defined in a local 12723 // 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. 12724 // function, so we shouldn't make new instances of it very often.
12545 uint32_t length = 0; 12725 uint32_t length = 0;
12546 CHECK(transition_info->length()->ToArrayIndex(&length)); 12726 CHECK(transition_info->length()->ToArrayIndex(&length));
12547 if (length <= AllocationSite::kMaximumArrayBytesToPretransition) { 12727 if (length <= AllocationSite::kMaximumArrayBytesToPretransition) {
12548 if (FLAG_trace_track_allocation_sites) { 12728 if (FLAG_trace_track_allocation_sites) {
12729 bool is_nested = site->IsNestedSite();
12549 PrintF( 12730 PrintF(
12550 "AllocationSite: JSArray %p boilerplate updated %s->%s\n", 12731 "AllocationSite: JSArray %p boilerplate %s updated %s->%s\n",
12551 reinterpret_cast<void*>(this), 12732 reinterpret_cast<void*>(this),
12733 is_nested ? "(nested)" : "",
12552 ElementsKindToString(kind), 12734 ElementsKindToString(kind),
12553 ElementsKindToString(to_kind)); 12735 ElementsKindToString(to_kind));
12554 } 12736 }
12555 return transition_info->TransitionElementsKind(to_kind); 12737 return transition_info->TransitionElementsKind(to_kind);
12556 } 12738 }
12557 } 12739 }
12558 } else { 12740 } else {
12559 ElementsKind kind = site->GetElementsKind(); 12741 ElementsKind kind = site->GetElementsKind();
12560 // if kind is holey ensure that to_kind is as well. 12742 // if kind is holey ensure that to_kind is as well.
12561 if (IsHoleyElementsKind(kind)) { 12743 if (IsHoleyElementsKind(kind)) {
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
12944 InterceptorInfo* JSObject::GetIndexedInterceptor() { 13126 InterceptorInfo* JSObject::GetIndexedInterceptor() {
12945 ASSERT(map()->has_indexed_interceptor()); 13127 ASSERT(map()->has_indexed_interceptor());
12946 JSFunction* constructor = JSFunction::cast(map()->constructor()); 13128 JSFunction* constructor = JSFunction::cast(map()->constructor());
12947 ASSERT(constructor->shared()->IsApiFunction()); 13129 ASSERT(constructor->shared()->IsApiFunction());
12948 Object* result = 13130 Object* result =
12949 constructor->shared()->get_api_func_data()->indexed_property_handler(); 13131 constructor->shared()->get_api_func_data()->indexed_property_handler();
12950 return InterceptorInfo::cast(result); 13132 return InterceptorInfo::cast(result);
12951 } 13133 }
12952 13134
12953 13135
12954 MaybeObject* JSObject::GetPropertyPostInterceptor( 13136 Handle<Object> JSObject::GetPropertyPostInterceptor(
12955 Object* receiver, 13137 Handle<JSObject> object,
12956 Name* name, 13138 Handle<Object> receiver,
13139 Handle<Name> name,
12957 PropertyAttributes* attributes) { 13140 PropertyAttributes* attributes) {
12958 // Check local property in holder, ignore interceptor. 13141 // Check local property in holder, ignore interceptor.
12959 LookupResult result(GetIsolate()); 13142 Isolate* isolate = object->GetIsolate();
12960 LocalLookupRealNamedProperty(name, &result); 13143 LookupResult lookup(isolate);
12961 if (result.IsFound()) { 13144 object->LocalLookupRealNamedProperty(*name, &lookup);
12962 return GetProperty(receiver, &result, name, attributes); 13145 Handle<Object> result;
13146 if (lookup.IsFound()) {
13147 result = GetProperty(object, receiver, &lookup, name, attributes);
13148 } else {
13149 // Continue searching via the prototype chain.
13150 Handle<Object> prototype(object->GetPrototype(), isolate);
13151 *attributes = ABSENT;
13152 if (prototype->IsNull()) return isolate->factory()->undefined_value();
13153 result = GetPropertyWithReceiver(prototype, receiver, name, attributes);
12963 } 13154 }
12964 // Continue searching via the prototype chain. 13155 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 } 13156 }
12970 13157
12971 13158
12972 MaybeObject* JSObject::GetLocalPropertyPostInterceptor( 13159 MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
12973 Object* receiver, 13160 Object* receiver,
12974 Name* name, 13161 Name* name,
12975 PropertyAttributes* attributes) { 13162 PropertyAttributes* attributes) {
12976 // Check local property in holder, ignore interceptor. 13163 // Check local property in holder, ignore interceptor.
12977 LookupResult result(GetIsolate()); 13164 LookupResult result(GetIsolate());
12978 LocalLookupRealNamedProperty(name, &result); 13165 LocalLookupRealNamedProperty(name, &result);
12979 if (result.IsFound()) { 13166 if (result.IsFound()) {
12980 return GetProperty(receiver, &result, name, attributes); 13167 return GetProperty(receiver, &result, name, attributes);
12981 } 13168 }
12982 return GetHeap()->undefined_value(); 13169 return GetHeap()->undefined_value();
12983 } 13170 }
12984 13171
12985 13172
12986 MaybeObject* JSObject::GetPropertyWithInterceptor( 13173 Handle<Object> JSObject::GetPropertyWithInterceptor(
12987 Object* receiver, 13174 Handle<JSObject> object,
12988 Name* name, 13175 Handle<Object> receiver,
13176 Handle<Name> name,
12989 PropertyAttributes* attributes) { 13177 PropertyAttributes* attributes) {
13178 Isolate* isolate = object->GetIsolate();
13179
12990 // TODO(rossberg): Support symbols in the API. 13180 // TODO(rossberg): Support symbols in the API.
12991 if (name->IsSymbol()) return GetHeap()->undefined_value(); 13181 if (name->IsSymbol()) return isolate->factory()->undefined_value();
12992 13182
12993 Isolate* isolate = GetIsolate(); 13183 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor(), isolate);
12994 InterceptorInfo* interceptor = GetNamedInterceptor(); 13184 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 13185
13000 if (!interceptor->getter()->IsUndefined()) { 13186 if (!interceptor->getter()->IsUndefined()) {
13001 v8::NamedPropertyGetterCallback getter = 13187 v8::NamedPropertyGetterCallback getter =
13002 v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter()); 13188 v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter());
13003 LOG(isolate, 13189 LOG(isolate,
13004 ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name)); 13190 ApiNamedPropertyAccess("interceptor-named-get", *object, *name));
13005 PropertyCallbackArguments 13191 PropertyCallbackArguments
13006 args(isolate, interceptor->data(), receiver, this); 13192 args(isolate, interceptor->data(), *receiver, *object);
13007 v8::Handle<v8::Value> result = 13193 v8::Handle<v8::Value> result =
13008 args.Call(getter, v8::Utils::ToLocal(name_handle)); 13194 args.Call(getter, v8::Utils::ToLocal(name_string));
13009 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 13195 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
13010 if (!result.IsEmpty()) { 13196 if (!result.IsEmpty()) {
13011 *attributes = NONE; 13197 *attributes = NONE;
13012 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); 13198 Handle<Object> result_internal = v8::Utils::OpenHandle(*result);
13013 result_internal->VerifyApiCallResultType(); 13199 result_internal->VerifyApiCallResultType();
13014 return *result_internal; 13200 // Rebox handle to escape this scope.
13201 return handle(*result_internal, isolate);
13015 } 13202 }
13016 } 13203 }
13017 13204
13018 MaybeObject* result = holder_handle->GetPropertyPostInterceptor( 13205 return GetPropertyPostInterceptor(object, receiver, name, attributes);
13019 *receiver_handle,
13020 *name_handle,
13021 attributes);
13022 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
13023 return result;
13024 } 13206 }
13025 13207
13026 13208
13027 bool JSObject::HasRealNamedProperty(Isolate* isolate, Name* key) { 13209 bool JSObject::HasRealNamedProperty(Handle<JSObject> object,
13210 Handle<Name> key) {
13211 Isolate* isolate = object->GetIsolate();
13212 SealHandleScope shs(isolate);
13028 // Check access rights if needed. 13213 // Check access rights if needed.
13029 if (IsAccessCheckNeeded()) { 13214 if (object->IsAccessCheckNeeded()) {
13030 if (!isolate->MayNamedAccess(this, key, v8::ACCESS_HAS)) { 13215 if (!isolate->MayNamedAccess(*object, *key, v8::ACCESS_HAS)) {
13031 isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS); 13216 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS);
13032 return false; 13217 return false;
13033 } 13218 }
13034 } 13219 }
13035 13220
13036 LookupResult result(isolate); 13221 LookupResult result(isolate);
13037 LocalLookupRealNamedProperty(key, &result); 13222 object->LocalLookupRealNamedProperty(*key, &result);
13038 return result.IsFound() && !result.IsInterceptor(); 13223 return result.IsFound() && !result.IsInterceptor();
13039 } 13224 }
13040 13225
13041 13226
13042 bool JSObject::HasRealElementProperty(Isolate* isolate, uint32_t index) { 13227 bool JSObject::HasRealElementProperty(Handle<JSObject> object, uint32_t index) {
13228 Isolate* isolate = object->GetIsolate();
13229 SealHandleScope shs(isolate);
13043 // Check access rights if needed. 13230 // Check access rights if needed.
13044 if (IsAccessCheckNeeded()) { 13231 if (object->IsAccessCheckNeeded()) {
13045 if (!isolate->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { 13232 if (!isolate->MayIndexedAccess(*object, index, v8::ACCESS_HAS)) {
13046 isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS); 13233 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS);
13047 return false; 13234 return false;
13048 } 13235 }
13049 } 13236 }
13050 13237
13051 if (IsJSGlobalProxy()) { 13238 if (object->IsJSGlobalProxy()) {
13052 Object* proto = GetPrototype(); 13239 HandleScope scope(isolate);
13240 Handle<Object> proto(object->GetPrototype(), isolate);
13053 if (proto->IsNull()) return false; 13241 if (proto->IsNull()) return false;
13054 ASSERT(proto->IsJSGlobalObject()); 13242 ASSERT(proto->IsJSGlobalObject());
13055 return JSObject::cast(proto)->HasRealElementProperty(isolate, index); 13243 return HasRealElementProperty(Handle<JSObject>::cast(proto), index);
13056 } 13244 }
13057 13245
13058 return GetElementAttributeWithoutInterceptor(this, index, false) != ABSENT; 13246 return object->GetElementAttributeWithoutInterceptor(
13247 *object, index, false) != ABSENT;
13059 } 13248 }
13060 13249
13061 13250
13062 bool JSObject::HasRealNamedCallbackProperty(Isolate* isolate, Name* key) { 13251 bool JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
13252 Handle<Name> key) {
13253 Isolate* isolate = object->GetIsolate();
13254 SealHandleScope shs(isolate);
13063 // Check access rights if needed. 13255 // Check access rights if needed.
13064 if (IsAccessCheckNeeded()) { 13256 if (object->IsAccessCheckNeeded()) {
13065 if (!isolate->MayNamedAccess(this, key, v8::ACCESS_HAS)) { 13257 if (!isolate->MayNamedAccess(*object, *key, v8::ACCESS_HAS)) {
13066 isolate->ReportFailedAccessCheck(this, v8::ACCESS_HAS); 13258 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_HAS);
13067 return false; 13259 return false;
13068 } 13260 }
13069 } 13261 }
13070 13262
13071 LookupResult result(isolate); 13263 LookupResult result(isolate);
13072 LocalLookupRealNamedProperty(key, &result); 13264 object->LocalLookupRealNamedProperty(*key, &result);
13073 return result.IsPropertyCallbacks(); 13265 return result.IsPropertyCallbacks();
13074 } 13266 }
13075 13267
13076 13268
13077 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { 13269 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) {
13078 if (HasFastProperties()) { 13270 if (HasFastProperties()) {
13079 Map* map = this->map(); 13271 Map* map = this->map();
13080 if (filter == NONE) return map->NumberOfOwnDescriptors(); 13272 if (filter == NONE) return map->NumberOfOwnDescriptors();
13081 if (filter & DONT_ENUM) { 13273 if (filter & DONT_ENUM) {
13082 int result = map->EnumLength(); 13274 int result = map->EnumLength();
(...skipping 3057 matching lines...) Expand 10 before | Expand all | Expand 10 after
16140 return static_cast<Type*>(type_raw()); 16332 return static_cast<Type*>(type_raw());
16141 } 16333 }
16142 16334
16143 16335
16144 void PropertyCell::set_type(Type* type, WriteBarrierMode ignored) { 16336 void PropertyCell::set_type(Type* type, WriteBarrierMode ignored) {
16145 ASSERT(IsPropertyCell()); 16337 ASSERT(IsPropertyCell());
16146 set_type_raw(type, ignored); 16338 set_type_raw(type, ignored);
16147 } 16339 }
16148 16340
16149 16341
16150 Type* PropertyCell::UpdateType(Handle<PropertyCell> cell, 16342 Handle<Type> PropertyCell::UpdatedType(Handle<PropertyCell> cell,
16151 Handle<Object> value) { 16343 Handle<Object> value) {
16152 Isolate* isolate = cell->GetIsolate(); 16344 Isolate* isolate = cell->GetIsolate();
16153 Handle<Type> old_type(cell->type(), isolate); 16345 Handle<Type> old_type(cell->type(), isolate);
16154 // TODO(2803): Do not track ConsString as constant because they cannot be 16346 // TODO(2803): Do not track ConsString as constant because they cannot be
16155 // embedded into code. 16347 // embedded into code.
16156 Handle<Type> new_type(value->IsConsString() || value->IsTheHole() 16348 Handle<Type> new_type(value->IsConsString() || value->IsTheHole()
16157 ? Type::Any() 16349 ? Type::Any()
16158 : Type::Constant(value, isolate), isolate); 16350 : Type::Constant(value, isolate), isolate);
16159 16351
16160 if (new_type->Is(old_type)) { 16352 if (new_type->Is(old_type)) {
16161 return *old_type; 16353 return old_type;
16162 } 16354 }
16163 16355
16164 cell->dependent_code()->DeoptimizeDependentCodeGroup( 16356 cell->dependent_code()->DeoptimizeDependentCodeGroup(
16165 isolate, DependentCode::kPropertyCellChangedGroup); 16357 isolate, DependentCode::kPropertyCellChangedGroup);
16166 16358
16167 if (old_type->Is(Type::None()) || old_type->Is(Type::Undefined())) { 16359 if (old_type->Is(Type::None()) || old_type->Is(Type::Undefined())) {
16168 return *new_type; 16360 return new_type;
16169 } 16361 }
16170 16362
16171 return Type::Any(); 16363 return handle(Type::Any(), isolate);
16172 } 16364 }
16173 16365
16174 16366
16175 void PropertyCell::SetValueInferType(Handle<PropertyCell> cell, 16367 void PropertyCell::SetValueInferType(Handle<PropertyCell> cell,
16176 Handle<Object> value, 16368 Handle<Object> value) {
16177 WriteBarrierMode mode) { 16369 cell->set_value(*value);
16178 CALL_HEAP_FUNCTION_VOID(cell->GetIsolate(), 16370 if (!Type::Any()->Is(cell->type())) {
16179 cell->SetValueInferType(*value, mode)); 16371 Handle<Type> new_type = UpdatedType(cell, value);
16372 cell->set_type(*new_type);
16373 }
16180 } 16374 }
16181 16375
16182 16376
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) { 16377 void PropertyCell::AddDependentCompilationInfo(CompilationInfo* info) {
16201 Handle<DependentCode> dep(dependent_code()); 16378 Handle<DependentCode> dep(dependent_code());
16202 Handle<DependentCode> codes = 16379 Handle<DependentCode> codes =
16203 DependentCode::Insert(dep, DependentCode::kPropertyCellChangedGroup, 16380 DependentCode::Insert(dep, DependentCode::kPropertyCellChangedGroup,
16204 info->object_wrapper()); 16381 info->object_wrapper());
16205 if (*codes != dependent_code()) set_dependent_code(*codes); 16382 if (*codes != dependent_code()) set_dependent_code(*codes);
16206 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( 16383 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add(
16207 Handle<HeapObject>(this), info->zone()); 16384 Handle<HeapObject>(this), info->zone());
16208 } 16385 }
16209 16386
(...skipping 11 matching lines...) Expand all
16221 #define ERROR_MESSAGES_TEXTS(C, T) T, 16398 #define ERROR_MESSAGES_TEXTS(C, T) T,
16222 static const char* error_messages_[] = { 16399 static const char* error_messages_[] = {
16223 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16400 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16224 }; 16401 };
16225 #undef ERROR_MESSAGES_TEXTS 16402 #undef ERROR_MESSAGES_TEXTS
16226 return error_messages_[reason]; 16403 return error_messages_[reason];
16227 } 16404 }
16228 16405
16229 16406
16230 } } // namespace v8::internal 16407 } } // 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