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

Side by Side Diff: src/accessors.cc

Issue 12319144: Avoid TLS accesses in Object::Lookup and Object::GetPrototype. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Simplified Object::GetPrototype a bit Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/api.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 24 matching lines...) Expand all
35 #include "frames-inl.h" 35 #include "frames-inl.h"
36 #include "isolate.h" 36 #include "isolate.h"
37 #include "list-inl.h" 37 #include "list-inl.h"
38 #include "property-details.h" 38 #include "property-details.h"
39 39
40 namespace v8 { 40 namespace v8 {
41 namespace internal { 41 namespace internal {
42 42
43 43
44 template <class C> 44 template <class C>
45 static C* FindInstanceOf(Object* obj) { 45 static C* FindInstanceOf(Isolate* isolate, Object* obj) {
46 for (Object* cur = obj; !cur->IsNull(); cur = cur->GetPrototype()) { 46 for (Object* cur = obj; !cur->IsNull(); cur = cur->GetPrototype(isolate)) {
47 if (Is<C>(cur)) return C::cast(cur); 47 if (Is<C>(cur)) return C::cast(cur);
48 } 48 }
49 return NULL; 49 return NULL;
50 } 50 }
51 51
52 52
53 // Entry point that never should be called. 53 // Entry point that never should be called.
54 MaybeObject* Accessors::IllegalSetter(JSObject*, Object*, void*) { 54 MaybeObject* Accessors::IllegalSetter(JSObject*, Object*, void*) {
55 UNREACHABLE(); 55 UNREACHABLE();
56 return NULL; 56 return NULL;
(...skipping 13 matching lines...) Expand all
70 } 70 }
71 71
72 72
73 // 73 //
74 // Accessors::ArrayLength 74 // Accessors::ArrayLength
75 // 75 //
76 76
77 77
78 MaybeObject* Accessors::ArrayGetLength(Object* object, void*) { 78 MaybeObject* Accessors::ArrayGetLength(Object* object, void*) {
79 // Traverse the prototype chain until we reach an array. 79 // Traverse the prototype chain until we reach an array.
80 JSArray* holder = FindInstanceOf<JSArray>(object); 80 JSArray* holder = FindInstanceOf<JSArray>(Isolate::Current(), object);
81 return holder == NULL ? Smi::FromInt(0) : holder->length(); 81 return holder == NULL ? Smi::FromInt(0) : holder->length();
82 } 82 }
83 83
84 84
85 // The helper function will 'flatten' Number objects. 85 // The helper function will 'flatten' Number objects.
86 Object* Accessors::FlattenNumber(Object* value) { 86 Object* Accessors::FlattenNumber(Object* value) {
87 if (value->IsNumber() || !value->IsJSValue()) return value; 87 if (value->IsNumber() || !value->IsJSValue()) return value;
88 JSValue* wrapper = JSValue::cast(value); 88 JSValue* wrapper = JSValue::cast(value);
89 ASSERT(Isolate::Current()->context()->native_context()->number_function()-> 89 ASSERT(Isolate::Current()->context()->native_context()->number_function()->
90 has_initial_map()); 90 has_initial_map());
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 0 435 0
436 }; 436 };
437 437
438 438
439 // 439 //
440 // Accessors::FunctionPrototype 440 // Accessors::FunctionPrototype
441 // 441 //
442 442
443 443
444 MaybeObject* Accessors::FunctionGetPrototype(Object* object, void*) { 444 MaybeObject* Accessors::FunctionGetPrototype(Object* object, void*) {
445 Heap* heap = Isolate::Current()->heap(); 445 Isolate* isolate = Isolate::Current();
446 JSFunction* function = FindInstanceOf<JSFunction>(object); 446 JSFunction* function = FindInstanceOf<JSFunction>(isolate, object);
447 if (function == NULL) return heap->undefined_value(); 447 if (function == NULL) return isolate->heap()->undefined_value();
448 while (!function->should_have_prototype()) { 448 while (!function->should_have_prototype()) {
449 function = FindInstanceOf<JSFunction>(function->GetPrototype()); 449 function = FindInstanceOf<JSFunction>(isolate, function->GetPrototype());
450 // There has to be one because we hit the getter. 450 // There has to be one because we hit the getter.
451 ASSERT(function != NULL); 451 ASSERT(function != NULL);
452 } 452 }
453 453
454 if (!function->has_prototype()) { 454 if (!function->has_prototype()) {
455 Object* prototype; 455 Object* prototype;
456 { MaybeObject* maybe_prototype = heap->AllocateFunctionPrototype(function); 456 { MaybeObject* maybe_prototype
457 = isolate->heap()->AllocateFunctionPrototype(function);
457 if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype; 458 if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype;
458 } 459 }
459 Object* result; 460 Object* result;
460 { MaybeObject* maybe_result = function->SetPrototype(prototype); 461 { MaybeObject* maybe_result = function->SetPrototype(prototype);
461 if (!maybe_result->ToObject(&result)) return maybe_result; 462 if (!maybe_result->ToObject(&result)) return maybe_result;
462 } 463 }
463 } 464 }
464 return function->prototype(); 465 return function->prototype();
465 } 466 }
466 467
467 468
468 MaybeObject* Accessors::FunctionSetPrototype(JSObject* object, 469 MaybeObject* Accessors::FunctionSetPrototype(JSObject* object,
469 Object* value_raw, 470 Object* value_raw,
470 void*) { 471 void*) {
471 Isolate* isolate = object->GetIsolate(); 472 Isolate* isolate = object->GetIsolate();
472 Heap* heap = isolate->heap(); 473 Heap* heap = isolate->heap();
473 JSFunction* function_raw = FindInstanceOf<JSFunction>(object); 474 JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, object);
474 if (function_raw == NULL) return heap->undefined_value(); 475 if (function_raw == NULL) return heap->undefined_value();
475 if (!function_raw->should_have_prototype()) { 476 if (!function_raw->should_have_prototype()) {
476 // Since we hit this accessor, object will have no prototype property. 477 // Since we hit this accessor, object will have no prototype property.
477 return object->SetLocalPropertyIgnoreAttributes(heap->prototype_symbol(), 478 return object->SetLocalPropertyIgnoreAttributes(heap->prototype_symbol(),
478 value_raw, 479 value_raw,
479 NONE); 480 NONE);
480 } 481 }
481 482
482 HandleScope scope(isolate); 483 HandleScope scope(isolate);
483 Handle<JSFunction> function(function_raw, isolate); 484 Handle<JSFunction> function(function_raw, isolate);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 0 516 0
516 }; 517 };
517 518
518 519
519 // 520 //
520 // Accessors::FunctionLength 521 // Accessors::FunctionLength
521 // 522 //
522 523
523 524
524 MaybeObject* Accessors::FunctionGetLength(Object* object, void*) { 525 MaybeObject* Accessors::FunctionGetLength(Object* object, void*) {
525 JSFunction* function = FindInstanceOf<JSFunction>(object); 526 Isolate* isolate = Isolate::Current();
527 JSFunction* function = FindInstanceOf<JSFunction>(isolate, object);
526 if (function == NULL) return Smi::FromInt(0); 528 if (function == NULL) return Smi::FromInt(0);
527 // Check if already compiled. 529 // Check if already compiled.
528 if (function->shared()->is_compiled()) { 530 if (function->shared()->is_compiled()) {
529 return Smi::FromInt(function->shared()->length()); 531 return Smi::FromInt(function->shared()->length());
530 } 532 }
531 // If the function isn't compiled yet, the length is not computed correctly 533 // If the function isn't compiled yet, the length is not computed correctly
532 // yet. Compile it now and return the right length. 534 // yet. Compile it now and return the right length.
533 HandleScope scope(function->GetIsolate()); 535 HandleScope scope(isolate);
534 Handle<JSFunction> handle(function); 536 Handle<JSFunction> handle(function);
535 if (JSFunction::CompileLazy(handle, KEEP_EXCEPTION)) { 537 if (JSFunction::CompileLazy(handle, KEEP_EXCEPTION)) {
536 return Smi::FromInt(handle->shared()->length()); 538 return Smi::FromInt(handle->shared()->length());
537 } 539 }
538 return Failure::Exception(); 540 return Failure::Exception();
539 } 541 }
540 542
541 543
542 const AccessorDescriptor Accessors::FunctionLength = { 544 const AccessorDescriptor Accessors::FunctionLength = {
543 FunctionGetLength, 545 FunctionGetLength,
544 ReadOnlySetAccessor, 546 ReadOnlySetAccessor,
545 0 547 0
546 }; 548 };
547 549
548 550
549 // 551 //
550 // Accessors::FunctionName 552 // Accessors::FunctionName
551 // 553 //
552 554
553 555
554 MaybeObject* Accessors::FunctionGetName(Object* object, void*) { 556 MaybeObject* Accessors::FunctionGetName(Object* object, void*) {
555 JSFunction* holder = FindInstanceOf<JSFunction>(object); 557 Isolate* isolate = Isolate::Current();
556 return holder == NULL ? HEAP->undefined_value() : holder->shared()->name(); 558 JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
559 return holder == NULL
560 ? isolate->heap()->undefined_value()
561 : holder->shared()->name();
557 } 562 }
558 563
559 564
560 const AccessorDescriptor Accessors::FunctionName = { 565 const AccessorDescriptor Accessors::FunctionName = {
561 FunctionGetName, 566 FunctionGetName,
562 ReadOnlySetAccessor, 567 ReadOnlySetAccessor,
563 0 568 0
564 }; 569 };
565 570
566 571
(...skipping 25 matching lines...) Expand all
592 args_slots.Dispose(); 597 args_slots.Dispose();
593 598
594 // Return the freshly allocated arguments object. 599 // Return the freshly allocated arguments object.
595 return *arguments; 600 return *arguments;
596 } 601 }
597 602
598 603
599 MaybeObject* Accessors::FunctionGetArguments(Object* object, void*) { 604 MaybeObject* Accessors::FunctionGetArguments(Object* object, void*) {
600 Isolate* isolate = Isolate::Current(); 605 Isolate* isolate = Isolate::Current();
601 HandleScope scope(isolate); 606 HandleScope scope(isolate);
602 JSFunction* holder = FindInstanceOf<JSFunction>(object); 607 JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
603 if (holder == NULL) return isolate->heap()->undefined_value(); 608 if (holder == NULL) return isolate->heap()->undefined_value();
604 Handle<JSFunction> function(holder, isolate); 609 Handle<JSFunction> function(holder, isolate);
605 610
606 if (function->shared()->native()) return isolate->heap()->null_value(); 611 if (function->shared()->native()) return isolate->heap()->null_value();
607 // Find the top invocation of the function by traversing frames. 612 // Find the top invocation of the function by traversing frames.
608 List<JSFunction*> functions(2); 613 List<JSFunction*> functions(2);
609 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) { 614 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
610 JavaScriptFrame* frame = it.frame(); 615 JavaScriptFrame* frame = it.frame();
611 frame->GetFunctions(&functions); 616 frame->GetFunctions(&functions);
612 for (int i = functions.length() - 1; i >= 0; i--) { 617 for (int i = functions.length() - 1; i >= 0; i--) {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 JavaScriptFrameIterator frame_iterator_; 721 JavaScriptFrameIterator frame_iterator_;
717 List<JSFunction*> functions_; 722 List<JSFunction*> functions_;
718 int index_; 723 int index_;
719 }; 724 };
720 725
721 726
722 MaybeObject* Accessors::FunctionGetCaller(Object* object, void*) { 727 MaybeObject* Accessors::FunctionGetCaller(Object* object, void*) {
723 Isolate* isolate = Isolate::Current(); 728 Isolate* isolate = Isolate::Current();
724 HandleScope scope(isolate); 729 HandleScope scope(isolate);
725 AssertNoAllocation no_alloc; 730 AssertNoAllocation no_alloc;
726 JSFunction* holder = FindInstanceOf<JSFunction>(object); 731 JSFunction* holder = FindInstanceOf<JSFunction>(isolate, object);
727 if (holder == NULL) return isolate->heap()->undefined_value(); 732 if (holder == NULL) return isolate->heap()->undefined_value();
728 if (holder->shared()->native()) return isolate->heap()->null_value(); 733 if (holder->shared()->native()) return isolate->heap()->null_value();
729 Handle<JSFunction> function(holder, isolate); 734 Handle<JSFunction> function(holder, isolate);
730 735
731 FrameFunctionIterator it(isolate, no_alloc); 736 FrameFunctionIterator it(isolate, no_alloc);
732 737
733 // Find the function from the frames. 738 // Find the function from the frames.
734 if (!it.Find(*function)) { 739 if (!it.Find(*function)) {
735 // No frame corresponding to the given function found. Return null. 740 // No frame corresponding to the given function found. Return null.
736 return isolate->heap()->null_value(); 741 return isolate->heap()->null_value();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 ReadOnlySetAccessor, 780 ReadOnlySetAccessor,
776 0 781 0
777 }; 782 };
778 783
779 784
780 // 785 //
781 // Accessors::ObjectPrototype 786 // Accessors::ObjectPrototype
782 // 787 //
783 788
784 789
785 static inline Object* GetPrototypeSkipHiddenPrototypes(Object* receiver) { 790 static inline Object* GetPrototypeSkipHiddenPrototypes(Isolate* isolate,
786 Object* current = receiver->GetPrototype(); 791 Object* receiver) {
792 Object* current = receiver->GetPrototype(isolate);
787 while (current->IsJSObject() && 793 while (current->IsJSObject() &&
788 JSObject::cast(current)->map()->is_hidden_prototype()) { 794 JSObject::cast(current)->map()->is_hidden_prototype()) {
789 current = current->GetPrototype(); 795 current = current->GetPrototype(isolate);
790 } 796 }
791 return current; 797 return current;
792 } 798 }
793 799
794 800
795 MaybeObject* Accessors::ObjectGetPrototype(Object* receiver, void*) { 801 MaybeObject* Accessors::ObjectGetPrototype(Object* receiver, void*) {
796 return GetPrototypeSkipHiddenPrototypes(receiver); 802 return GetPrototypeSkipHiddenPrototypes(Isolate::Current(), receiver);
797 } 803 }
798 804
799 805
800 MaybeObject* Accessors::ObjectSetPrototype(JSObject* receiver_raw, 806 MaybeObject* Accessors::ObjectSetPrototype(JSObject* receiver_raw,
801 Object* value_raw, 807 Object* value_raw,
802 void*) { 808 void*) {
803 const bool kSkipHiddenPrototypes = true; 809 const bool kSkipHiddenPrototypes = true;
804 // To be consistent with other Set functions, return the value. 810 // To be consistent with other Set functions, return the value.
805 if (!(FLAG_harmony_observation && receiver_raw->map()->is_observed())) 811 if (!(FLAG_harmony_observation && receiver_raw->map()->is_observed()))
806 return receiver_raw->SetPrototype(value_raw, kSkipHiddenPrototypes); 812 return receiver_raw->SetPrototype(value_raw, kSkipHiddenPrototypes);
807 813
808 Isolate* isolate = receiver_raw->GetIsolate(); 814 Isolate* isolate = receiver_raw->GetIsolate();
809 HandleScope scope(isolate); 815 HandleScope scope(isolate);
810 Handle<JSObject> receiver(receiver_raw); 816 Handle<JSObject> receiver(receiver_raw);
811 Handle<Object> value(value_raw, isolate); 817 Handle<Object> value(value_raw, isolate);
812 Handle<Object> old_value(GetPrototypeSkipHiddenPrototypes(*receiver), 818 Handle<Object> old_value(GetPrototypeSkipHiddenPrototypes(isolate, *receiver),
813 isolate); 819 isolate);
814 820
815 MaybeObject* result = receiver->SetPrototype(*value, kSkipHiddenPrototypes); 821 MaybeObject* result = receiver->SetPrototype(*value, kSkipHiddenPrototypes);
816 Handle<Object> hresult; 822 Handle<Object> hresult;
817 if (!result->ToHandle(&hresult, isolate)) return result; 823 if (!result->ToHandle(&hresult, isolate)) return result;
818 824
819 Handle<Object> new_value(GetPrototypeSkipHiddenPrototypes(*receiver), 825 Handle<Object> new_value(GetPrototypeSkipHiddenPrototypes(isolate, *receiver),
820 isolate); 826 isolate);
821 if (!new_value->SameValue(*old_value)) { 827 if (!new_value->SameValue(*old_value)) {
822 JSObject::EnqueueChangeRecord(receiver, "prototype", 828 JSObject::EnqueueChangeRecord(receiver, "prototype",
823 isolate->factory()->Proto_symbol(), 829 isolate->factory()->Proto_symbol(),
824 old_value); 830 old_value);
825 } 831 }
826 return *hresult; 832 return *hresult;
827 } 833 }
828 834
829 835
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 info->set_data(Smi::FromInt(index)); 898 info->set_data(Smi::FromInt(index));
893 Handle<Object> getter = v8::FromCData(&ModuleGetExport); 899 Handle<Object> getter = v8::FromCData(&ModuleGetExport);
894 Handle<Object> setter = v8::FromCData(&ModuleSetExport); 900 Handle<Object> setter = v8::FromCData(&ModuleSetExport);
895 info->set_getter(*getter); 901 info->set_getter(*getter);
896 if (!(attributes & ReadOnly)) info->set_setter(*setter); 902 if (!(attributes & ReadOnly)) info->set_setter(*setter);
897 return info; 903 return info;
898 } 904 }
899 905
900 906
901 } } // namespace v8::internal 907 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698