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

Side by Side Diff: src/runtime.cc

Issue 8416014: Force transition to FAST_ELEMENTS on out-of-bounds KeyedLoads. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: review feedback Created 9 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 | « no previous file | test/mjsunit/unbox-double-arrays.js » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 4153 matching lines...) Expand 10 before | Expand all | Expand 10 after
4164 NoHandleAllocation ha; 4164 NoHandleAllocation ha;
4165 ASSERT(args.length() == 2); 4165 ASSERT(args.length() == 2);
4166 4166
4167 Handle<Object> object = args.at<Object>(0); 4167 Handle<Object> object = args.at<Object>(0);
4168 Handle<Object> key = args.at<Object>(1); 4168 Handle<Object> key = args.at<Object>(1);
4169 4169
4170 return Runtime::GetObjectProperty(isolate, object, key); 4170 return Runtime::GetObjectProperty(isolate, object, key);
4171 } 4171 }
4172 4172
4173 4173
4174 MaybeObject* TransitionElements(Handle<Object> object,
4175 ElementsKind to_kind,
4176 Isolate* isolate) {
4177 HandleScope scope(isolate);
4178 if (!object->IsJSObject()) return isolate->ThrowIllegalOperation();
4179 ElementsKind from_kind =
4180 Handle<JSObject>::cast(object)->map()->elements_kind();
4181 if (Map::IsValidElementsTransition(from_kind, to_kind)) {
4182 Handle<Object> result =
4183 TransitionElementsKind(Handle<JSObject>::cast(object), to_kind);
4184 if (result.is_null()) return isolate->ThrowIllegalOperation();
4185 return *result;
4186 }
4187 return isolate->ThrowIllegalOperation();
4188 }
4189
4190
4174 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. 4191 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric.
4175 RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) { 4192 RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) {
4176 NoHandleAllocation ha; 4193 NoHandleAllocation ha;
4177 ASSERT(args.length() == 2); 4194 ASSERT(args.length() == 2);
4178 4195
4179 // Fast cases for getting named properties of the receiver JSObject 4196 // Fast cases for getting named properties of the receiver JSObject
4180 // itself. 4197 // itself.
4181 // 4198 //
4182 // The global proxy objects has to be excluded since LocalLookup on 4199 // The global proxy objects has to be excluded since LocalLookup on
4183 // the global proxy object can return a valid result even though the 4200 // the global proxy object can return a valid result even though the
4184 // global proxy object never has properties. This is the case 4201 // global proxy object never has properties. This is the case
4185 // because the global proxy object forwards everything to its hidden 4202 // because the global proxy object forwards everything to its hidden
4186 // prototype including local lookups. 4203 // prototype including local lookups.
4187 // 4204 //
4188 // Additionally, we need to make sure that we do not cache results 4205 // Additionally, we need to make sure that we do not cache results
4189 // for objects that require access checks. 4206 // for objects that require access checks.
4190 if (args[0]->IsJSObject() && 4207 if (args[0]->IsJSObject()) {
4191 !args[0]->IsJSGlobalProxy() && 4208 if (!args[0]->IsJSGlobalProxy() &&
4192 !args[0]->IsAccessCheckNeeded() && 4209 !args[0]->IsAccessCheckNeeded() &&
4193 args[1]->IsString()) { 4210 args[1]->IsString()) {
4194 JSObject* receiver = JSObject::cast(args[0]); 4211 JSObject* receiver = JSObject::cast(args[0]);
4195 String* key = String::cast(args[1]); 4212 String* key = String::cast(args[1]);
4196 if (receiver->HasFastProperties()) { 4213 if (receiver->HasFastProperties()) {
4197 // Attempt to use lookup cache. 4214 // Attempt to use lookup cache.
4198 Map* receiver_map = receiver->map(); 4215 Map* receiver_map = receiver->map();
4199 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache(); 4216 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
4200 int offset = keyed_lookup_cache->Lookup(receiver_map, key); 4217 int offset = keyed_lookup_cache->Lookup(receiver_map, key);
4201 if (offset != -1) { 4218 if (offset != -1) {
4202 Object* value = receiver->FastPropertyAt(offset); 4219 Object* value = receiver->FastPropertyAt(offset);
4203 return value->IsTheHole() ? isolate->heap()->undefined_value() : value; 4220 return value->IsTheHole()
4221 ? isolate->heap()->undefined_value()
4222 : value;
4223 }
4224 // Lookup cache miss. Perform lookup and update the cache if
4225 // appropriate.
4226 LookupResult result(isolate);
4227 receiver->LocalLookup(key, &result);
4228 if (result.IsProperty() && result.type() == FIELD) {
4229 int offset = result.GetFieldIndex();
4230 keyed_lookup_cache->Update(receiver_map, key, offset);
4231 return receiver->FastPropertyAt(offset);
4232 }
4233 } else {
4234 // Attempt dictionary lookup.
4235 StringDictionary* dictionary = receiver->property_dictionary();
4236 int entry = dictionary->FindEntry(key);
4237 if ((entry != StringDictionary::kNotFound) &&
4238 (dictionary->DetailsAt(entry).type() == NORMAL)) {
4239 Object* value = dictionary->ValueAt(entry);
4240 if (!receiver->IsGlobalObject()) return value;
4241 value = JSGlobalPropertyCell::cast(value)->value();
4242 if (!value->IsTheHole()) return value;
4243 // If value is the hole do the general lookup.
4244 }
4204 } 4245 }
4205 // Lookup cache miss. Perform lookup and update the cache if appropriate. 4246 } else if (FLAG_smi_only_arrays && args.at<Object>(1)->IsSmi()) {
4206 LookupResult result(isolate); 4247 // JSObject without a string key. If the key is a Smi, check for a
4207 receiver->LocalLookup(key, &result); 4248 // definite out-of-bounds access to elements, which is a strong indicator
4208 if (result.IsProperty() && result.type() == FIELD) { 4249 // that subsequent accesses will also call the runtime. Proactively
4209 int offset = result.GetFieldIndex(); 4250 // transition elements to FAST_ELEMENTS to avoid excessive boxing of
4210 keyed_lookup_cache->Update(receiver_map, key, offset); 4251 // doubles for those future calls in the case that the elements would
4211 return receiver->FastPropertyAt(offset); 4252 // become FAST_DOUBLE_ELEMENTS.
4212 } 4253 Handle<JSObject> js_object(args.at<JSObject>(0));
4213 } else { 4254 ElementsKind elements_kind = js_object->GetElementsKind();
4214 // Attempt dictionary lookup. 4255 if (elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4215 StringDictionary* dictionary = receiver->property_dictionary(); 4256 elements_kind == FAST_DOUBLE_ELEMENTS) {
4216 int entry = dictionary->FindEntry(key); 4257 FixedArrayBase* elements = js_object->elements();
4217 if ((entry != StringDictionary::kNotFound) && 4258 if (args.at<Smi>(1)->value() >= elements->length()) {
4218 (dictionary->DetailsAt(entry).type() == NORMAL)) { 4259 MaybeObject* maybe_object = TransitionElements(js_object,
4219 Object* value = dictionary->ValueAt(entry); 4260 FAST_ELEMENTS,
4220 if (!receiver->IsGlobalObject()) return value; 4261 isolate);
4221 value = JSGlobalPropertyCell::cast(value)->value(); 4262 if (maybe_object->IsFailure()) return maybe_object;
4222 if (!value->IsTheHole()) return value; 4263 }
4223 // If value is the hole do the general lookup.
4224 } 4264 }
4225 } 4265 }
4226 } else if (args[0]->IsString() && args[1]->IsSmi()) { 4266 } else if (args[0]->IsString() && args[1]->IsSmi()) {
4227 // Fast case for string indexing using [] with a smi index. 4267 // Fast case for string indexing using [] with a smi index.
4228 HandleScope scope(isolate); 4268 HandleScope scope(isolate);
4229 Handle<String> str = args.at<String>(0); 4269 Handle<String> str = args.at<String>(0);
4230 int index = args.smi_at(1); 4270 int index = args.smi_at(1);
4231 if (index >= 0 && index < str->length()) { 4271 if (index >= 0 && index < str->length()) {
4232 Handle<Object> result = GetCharAt(str, index); 4272 Handle<Object> result = GetCharAt(str, index);
4233 return *result; 4273 return *result;
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
4602 4642
4603 return Runtime::SetObjectProperty(isolate, 4643 return Runtime::SetObjectProperty(isolate,
4604 object, 4644 object,
4605 key, 4645 key,
4606 value, 4646 value,
4607 attributes, 4647 attributes,
4608 strict_mode); 4648 strict_mode);
4609 } 4649 }
4610 4650
4611 4651
4612 MaybeObject* TransitionElements(Handle<Object> object,
4613 ElementsKind to_kind,
4614 Isolate* isolate) {
4615 HandleScope scope(isolate);
4616 if (!object->IsJSObject()) return isolate->ThrowIllegalOperation();
4617 ElementsKind from_kind =
4618 Handle<JSObject>::cast(object)->map()->elements_kind();
4619 if (Map::IsValidElementsTransition(from_kind, to_kind)) {
4620 Handle<Object> result =
4621 TransitionElementsKind(Handle<JSObject>::cast(object), to_kind);
4622 if (result.is_null()) return isolate->ThrowIllegalOperation();
4623 return *result;
4624 }
4625 return isolate->ThrowIllegalOperation();
4626 }
4627
4628
4629 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsSmiToDouble) { 4652 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsSmiToDouble) {
4630 NoHandleAllocation ha; 4653 NoHandleAllocation ha;
4631 RUNTIME_ASSERT(args.length() == 1); 4654 RUNTIME_ASSERT(args.length() == 1);
4632 Handle<Object> object = args.at<Object>(0); 4655 Handle<Object> object = args.at<Object>(0);
4633 return TransitionElements(object, FAST_DOUBLE_ELEMENTS, isolate); 4656 return TransitionElements(object, FAST_DOUBLE_ELEMENTS, isolate);
4634 } 4657 }
4635 4658
4636 4659
4637 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsDoubleToObject) { 4660 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsDoubleToObject) {
4638 NoHandleAllocation ha; 4661 NoHandleAllocation ha;
(...skipping 8886 matching lines...) Expand 10 before | Expand all | Expand 10 after
13525 } else { 13548 } else {
13526 // Handle last resort GC and make sure to allow future allocations 13549 // Handle last resort GC and make sure to allow future allocations
13527 // to grow the heap without causing GCs (if possible). 13550 // to grow the heap without causing GCs (if possible).
13528 isolate->counters()->gc_last_resort_from_js()->Increment(); 13551 isolate->counters()->gc_last_resort_from_js()->Increment();
13529 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); 13552 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags);
13530 } 13553 }
13531 } 13554 }
13532 13555
13533 13556
13534 } } // namespace v8::internal 13557 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/unbox-double-arrays.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698