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

Side by Side Diff: src/runtime.cc

Issue 300283002: Introduce FieldIndex to unify and abstract property/field offset (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix mutable boxed double runtime function Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/property.cc ('k') | src/string-stream.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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdlib.h> 5 #include <stdlib.h>
6 #include <limits> 6 #include <limits>
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/accessors.h" 10 #include "src/accessors.h"
(...skipping 2537 matching lines...) Expand 10 before | Expand all | Expand 10 after
2548 JSReceiver::SetProperty(global, name, value, attributes, SLOPPY)); 2548 JSReceiver::SetProperty(global, name, value, attributes, SLOPPY));
2549 return *value; 2549 return *value;
2550 } 2550 }
2551 2551
2552 // Set the value, but only if we're assigning the initial value to a 2552 // Set the value, but only if we're assigning the initial value to a
2553 // constant. For now, we determine this by checking if the 2553 // constant. For now, we determine this by checking if the
2554 // current value is the hole. 2554 // current value is the hole.
2555 // Strict mode handling not needed (const is disallowed in strict mode). 2555 // Strict mode handling not needed (const is disallowed in strict mode).
2556 if (lookup.IsField()) { 2556 if (lookup.IsField()) {
2557 FixedArray* properties = global->properties(); 2557 FixedArray* properties = global->properties();
2558 int index = lookup.GetFieldIndex().field_index(); 2558 int index = lookup.GetFieldIndex().outobject_array_index();
2559 if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) { 2559 if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) {
2560 properties->set(index, *value); 2560 properties->set(index, *value);
2561 } 2561 }
2562 } else if (lookup.IsNormal()) { 2562 } else if (lookup.IsNormal()) {
2563 if (global->GetNormalizedProperty(&lookup)->IsTheHole() || 2563 if (global->GetNormalizedProperty(&lookup)->IsTheHole() ||
2564 !lookup.IsReadOnly()) { 2564 !lookup.IsReadOnly()) {
2565 HandleScope scope(isolate); 2565 HandleScope scope(isolate);
2566 JSObject::SetNormalizedProperty(Handle<JSObject>(global), &lookup, value); 2566 JSObject::SetNormalizedProperty(Handle<JSObject>(global), &lookup, value);
2567 } 2567 }
2568 } else { 2568 } else {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2637 // This is the property that was introduced by the const declaration. 2637 // This is the property that was introduced by the const declaration.
2638 // Set it if it hasn't been set before. NOTE: We cannot use 2638 // Set it if it hasn't been set before. NOTE: We cannot use
2639 // GetProperty() to get the current value as it 'unholes' the value. 2639 // GetProperty() to get the current value as it 'unholes' the value.
2640 LookupResult lookup(isolate); 2640 LookupResult lookup(isolate);
2641 object->LookupOwnRealNamedProperty(name, &lookup); 2641 object->LookupOwnRealNamedProperty(name, &lookup);
2642 ASSERT(lookup.IsFound()); // the property was declared 2642 ASSERT(lookup.IsFound()); // the property was declared
2643 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only 2643 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only
2644 2644
2645 if (lookup.IsField()) { 2645 if (lookup.IsField()) {
2646 FixedArray* properties = object->properties(); 2646 FixedArray* properties = object->properties();
2647 int index = lookup.GetFieldIndex().field_index(); 2647 FieldIndex index = lookup.GetFieldIndex();
2648 if (properties->get(index)->IsTheHole()) { 2648 ASSERT(!index.is_inobject());
2649 properties->set(index, *value); 2649 if (properties->get(index.outobject_array_index())->IsTheHole()) {
2650 properties->set(index.outobject_array_index(), *value);
2650 } 2651 }
2651 } else if (lookup.IsNormal()) { 2652 } else if (lookup.IsNormal()) {
2652 if (object->GetNormalizedProperty(&lookup)->IsTheHole()) { 2653 if (object->GetNormalizedProperty(&lookup)->IsTheHole()) {
2653 JSObject::SetNormalizedProperty(object, &lookup, value); 2654 JSObject::SetNormalizedProperty(object, &lookup, value);
2654 } 2655 }
2655 } else { 2656 } else {
2656 // We should not reach here. Any real, named property should be 2657 // We should not reach here. Any real, named property should be
2657 // either a field or a dictionary slot. 2658 // either a field or a dictionary slot.
2658 UNREACHABLE(); 2659 UNREACHABLE();
2659 } 2660 }
(...skipping 2386 matching lines...) Expand 10 before | Expand all | Expand 10 after
5046 if (!receiver_obj->IsJSGlobalProxy() && 5047 if (!receiver_obj->IsJSGlobalProxy() &&
5047 !receiver_obj->IsAccessCheckNeeded() && 5048 !receiver_obj->IsAccessCheckNeeded() &&
5048 key_obj->IsName()) { 5049 key_obj->IsName()) {
5049 DisallowHeapAllocation no_allocation; 5050 DisallowHeapAllocation no_allocation;
5050 Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj); 5051 Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
5051 Handle<Name> key = Handle<Name>::cast(key_obj); 5052 Handle<Name> key = Handle<Name>::cast(key_obj);
5052 if (receiver->HasFastProperties()) { 5053 if (receiver->HasFastProperties()) {
5053 // Attempt to use lookup cache. 5054 // Attempt to use lookup cache.
5054 Handle<Map> receiver_map(receiver->map(), isolate); 5055 Handle<Map> receiver_map(receiver->map(), isolate);
5055 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache(); 5056 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
5056 int offset = keyed_lookup_cache->Lookup(receiver_map, key); 5057 int index = keyed_lookup_cache->Lookup(receiver_map, key);
5057 if (offset != -1) { 5058 if (index != -1) {
5058 // Doubles are not cached, so raw read the value. 5059 // Doubles are not cached, so raw read the value.
5059 Object* value = receiver->RawFastPropertyAt(offset); 5060 Object* value = receiver->RawFastPropertyAt(
5061 FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index));
5060 return value->IsTheHole() 5062 return value->IsTheHole()
5061 ? isolate->heap()->undefined_value() 5063 ? isolate->heap()->undefined_value()
5062 : value; 5064 : value;
5063 } 5065 }
5064 // Lookup cache miss. Perform lookup and update the cache if 5066 // Lookup cache miss. Perform lookup and update the cache if
5065 // appropriate. 5067 // appropriate.
5066 LookupResult result(isolate); 5068 LookupResult result(isolate);
5067 receiver->LookupOwn(key, &result); 5069 receiver->LookupOwn(key, &result);
5068 if (result.IsField()) { 5070 if (result.IsField()) {
5069 int offset = result.GetFieldIndex().field_index(); 5071 FieldIndex field_index = result.GetFieldIndex();
5070 // Do not track double fields in the keyed lookup cache. Reading 5072 // Do not track double fields in the keyed lookup cache. Reading
5071 // double values requires boxing. 5073 // double values requires boxing.
5072 if (!result.representation().IsDouble()) { 5074 if (!result.representation().IsDouble()) {
5073 keyed_lookup_cache->Update(receiver_map, key, offset); 5075 keyed_lookup_cache->Update(receiver_map, key,
5076 field_index.GetKeyedLookupCacheIndex());
5074 } 5077 }
5075 AllowHeapAllocation allow_allocation; 5078 AllowHeapAllocation allow_allocation;
5076 return *JSObject::FastPropertyAt( 5079 return *JSObject::FastPropertyAt(receiver, result.representation(),
5077 receiver, result.representation(), offset); 5080 field_index);
5078 } 5081 }
5079 } else { 5082 } else {
5080 // Attempt dictionary lookup. 5083 // Attempt dictionary lookup.
5081 NameDictionary* dictionary = receiver->property_dictionary(); 5084 NameDictionary* dictionary = receiver->property_dictionary();
5082 int entry = dictionary->FindEntry(key); 5085 int entry = dictionary->FindEntry(key);
5083 if ((entry != NameDictionary::kNotFound) && 5086 if ((entry != NameDictionary::kNotFound) &&
5084 (dictionary->DetailsAt(entry).type() == NORMAL)) { 5087 (dictionary->DetailsAt(entry).type() == NORMAL)) {
5085 Object* value = dictionary->ValueAt(entry); 5088 Object* value = dictionary->ValueAt(entry);
5086 if (!receiver->IsGlobalObject()) return value; 5089 if (!receiver->IsGlobalObject()) return value;
5087 value = PropertyCell::cast(value)->value(); 5090 value = PropertyCell::cast(value)->value();
(...skipping 5681 matching lines...) Expand 10 before | Expand all | Expand 10 after
10769 Handle<Object> value = isolate->factory()->undefined_value(); 10772 Handle<Object> value = isolate->factory()->undefined_value();
10770 if (!result->IsFound()) return value; 10773 if (!result->IsFound()) return value;
10771 switch (result->type()) { 10774 switch (result->type()) {
10772 case NORMAL: 10775 case NORMAL:
10773 value = JSObject::GetNormalizedProperty( 10776 value = JSObject::GetNormalizedProperty(
10774 handle(result->holder(), isolate), result); 10777 handle(result->holder(), isolate), result);
10775 break; 10778 break;
10776 case FIELD: 10779 case FIELD:
10777 value = JSObject::FastPropertyAt(handle(result->holder(), isolate), 10780 value = JSObject::FastPropertyAt(handle(result->holder(), isolate),
10778 result->representation(), 10781 result->representation(),
10779 result->GetFieldIndex().field_index()); 10782 result->GetFieldIndex());
10780 break; 10783 break;
10781 case CONSTANT: 10784 case CONSTANT:
10782 return handle(result->GetConstant(), isolate); 10785 return handle(result->GetConstant(), isolate);
10783 case CALLBACKS: { 10786 case CALLBACKS: {
10784 Handle<Object> structure(result->GetCallbackObject(), isolate); 10787 Handle<Object> structure(result->GetCallbackObject(), isolate);
10785 ASSERT(!structure->IsForeign()); 10788 ASSERT(!structure->IsForeign());
10786 if (structure->IsAccessorInfo()) { 10789 if (structure->IsAccessorInfo()) {
10787 MaybeHandle<Object> obj = JSObject::GetPropertyWithCallback( 10790 MaybeHandle<Object> obj = JSObject::GetPropertyWithCallback(
10788 receiver, name, handle(result->holder(), isolate), structure); 10791 receiver, name, handle(result->holder(), isolate), structure);
10789 if (!obj.ToHandle(&value)) { 10792 if (!obj.ToHandle(&value)) {
(...skipping 3748 matching lines...) Expand 10 before | Expand all | Expand 10 after
14538 isolate->heap()->NotifyContextDisposed(); 14541 isolate->heap()->NotifyContextDisposed();
14539 return isolate->heap()->undefined_value(); 14542 return isolate->heap()->undefined_value();
14540 } 14543 }
14541 14544
14542 14545
14543 RUNTIME_FUNCTION(Runtime_LoadMutableDouble) { 14546 RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
14544 HandleScope scope(isolate); 14547 HandleScope scope(isolate);
14545 ASSERT(args.length() == 2); 14548 ASSERT(args.length() == 2);
14546 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 14549 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
14547 CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1); 14550 CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
14548 int idx = index->value() >> 1; 14551 RUNTIME_ASSERT((index->value() & 1) == 1);
14549 int inobject_properties = object->map()->inobject_properties(); 14552 FieldIndex field_index =
14550 if (idx < 0) { 14553 FieldIndex::ForLoadByFieldIndex(object->map(), index->value());
14551 idx = -idx + inobject_properties - 1; 14554 if (field_index.is_inobject()) {
14555 RUNTIME_ASSERT(field_index.property_index() <
14556 object->map()->inobject_properties());
14557 } else {
14558 RUNTIME_ASSERT(field_index.outobject_array_index() <
14559 object->properties()->length());
14552 } 14560 }
14553 int max_idx = object->properties()->length() + inobject_properties; 14561 Handle<Object> raw_value(object->RawFastPropertyAt(field_index), isolate);
14554 RUNTIME_ASSERT(idx < max_idx);
14555 Handle<Object> raw_value(object->RawFastPropertyAt(idx), isolate);
14556 RUNTIME_ASSERT(raw_value->IsNumber() || raw_value->IsUninitialized()); 14562 RUNTIME_ASSERT(raw_value->IsNumber() || raw_value->IsUninitialized());
14557 return *Object::NewStorageFor(isolate, raw_value, Representation::Double()); 14563 return *Object::NewStorageFor(isolate, raw_value, Representation::Double());
14558 } 14564 }
14559 14565
14560 14566
14561 RUNTIME_FUNCTION(Runtime_TryMigrateInstance) { 14567 RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
14562 HandleScope scope(isolate); 14568 HandleScope scope(isolate);
14563 ASSERT(args.length() == 1); 14569 ASSERT(args.length() == 1);
14564 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); 14570 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
14565 if (!object->IsJSObject()) return Smi::FromInt(0); 14571 if (!object->IsJSObject()) return Smi::FromInt(0);
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after
15138 } 15144 }
15139 return NULL; 15145 return NULL;
15140 } 15146 }
15141 15147
15142 15148
15143 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { 15149 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
15144 return &(kIntrinsicFunctions[static_cast<int>(id)]); 15150 return &(kIntrinsicFunctions[static_cast<int>(id)]);
15145 } 15151 }
15146 15152
15147 } } // namespace v8::internal 15153 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/property.cc ('k') | src/string-stream.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698