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

Side by Side Diff: src/runtime.cc

Issue 24093002: Use trampoline or handlified JSObject::SetLocalPropertyIgnoreAttributes. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments by Toon Verwaest. Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | no next file » | 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 2258 matching lines...) Expand 10 before | Expand all | Expand 10 after
2269 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); 2269 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
2270 2270
2271 // Lookup the property locally in the global object. If it isn't 2271 // Lookup the property locally in the global object. If it isn't
2272 // there, we add the property and take special precautions to always 2272 // there, we add the property and take special precautions to always
2273 // add it as a local property even in case of callbacks in the 2273 // add it as a local property even in case of callbacks in the
2274 // prototype chain (this rules out using SetProperty). 2274 // prototype chain (this rules out using SetProperty).
2275 // We use SetLocalPropertyIgnoreAttributes instead 2275 // We use SetLocalPropertyIgnoreAttributes instead
2276 LookupResult lookup(isolate); 2276 LookupResult lookup(isolate);
2277 global->LocalLookup(*name, &lookup); 2277 global->LocalLookup(*name, &lookup);
2278 if (!lookup.IsFound()) { 2278 if (!lookup.IsFound()) {
2279 return global->SetLocalPropertyIgnoreAttributes(*name, 2279 HandleScope handle_scope(isolate);
2280 *value, 2280 Handle<GlobalObject> global(isolate->context()->global_object());
2281 attributes); 2281 RETURN_IF_EMPTY_HANDLE(
2282 isolate,
2283 JSObject::SetLocalPropertyIgnoreAttributes(global, name, value,
2284 attributes));
2285 return *value;
2282 } 2286 }
2283 2287
2284 if (!lookup.IsReadOnly()) { 2288 if (!lookup.IsReadOnly()) {
2285 // Restore global object from context (in case of GC) and continue 2289 // Restore global object from context (in case of GC) and continue
2286 // with setting the value. 2290 // with setting the value.
2287 HandleScope handle_scope(isolate); 2291 HandleScope handle_scope(isolate);
2288 Handle<GlobalObject> global(isolate->context()->global_object()); 2292 Handle<GlobalObject> global(isolate->context()->global_object());
2289 2293
2290 // BUG 1213575: Handle the case where we have to set a read-only 2294 // BUG 1213575: Handle the case where we have to set a read-only
2291 // property through an interceptor and only do it if it's 2295 // property through an interceptor and only do it if it's
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
2488 array->set_elements(elements); 2492 array->set_elements(elements);
2489 array->set_length(Smi::FromInt(elements_count)); 2493 array->set_length(Smi::FromInt(elements_count));
2490 // Write in-object properties after the length of the array. 2494 // Write in-object properties after the length of the array.
2491 array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, args[1]); 2495 array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, args[1]);
2492 array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]); 2496 array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, args[2]);
2493 return array; 2497 return array;
2494 } 2498 }
2495 2499
2496 2500
2497 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpInitializeObject) { 2501 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpInitializeObject) {
2498 SealHandleScope shs(isolate); 2502 HandleScope scope(isolate);
2499 DisallowHeapAllocation no_allocation; 2503 DisallowHeapAllocation no_allocation;
2500 ASSERT(args.length() == 5); 2504 ASSERT(args.length() == 5);
2501 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); 2505 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
2502 CONVERT_ARG_CHECKED(String, source, 1); 2506 CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
2503 // If source is the empty string we set it to "(?:)" instead as 2507 // If source is the empty string we set it to "(?:)" instead as
2504 // suggested by ECMA-262, 5th, section 15.10.4.1. 2508 // suggested by ECMA-262, 5th, section 15.10.4.1.
2505 if (source->length() == 0) source = isolate->heap()->query_colon_string(); 2509 if (source->length() == 0) source = isolate->factory()->query_colon_string();
2506 2510
2507 Object* global = args[2]; 2511 CONVERT_ARG_HANDLE_CHECKED(Object, global, 2);
2508 if (!global->IsTrue()) global = isolate->heap()->false_value(); 2512 if (!global->IsTrue()) global = isolate->factory()->false_value();
2509 2513
2510 Object* ignoreCase = args[3]; 2514 CONVERT_ARG_HANDLE_CHECKED(Object, ignoreCase, 3);
2511 if (!ignoreCase->IsTrue()) ignoreCase = isolate->heap()->false_value(); 2515 if (!ignoreCase->IsTrue()) ignoreCase = isolate->factory()->false_value();
2512 2516
2513 Object* multiline = args[4]; 2517 CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4);
2514 if (!multiline->IsTrue()) multiline = isolate->heap()->false_value(); 2518 if (!multiline->IsTrue()) multiline = isolate->factory()->false_value();
2515 2519
2516 Map* map = regexp->map(); 2520 Map* map = regexp->map();
2517 Object* constructor = map->constructor(); 2521 Object* constructor = map->constructor();
2518 if (constructor->IsJSFunction() && 2522 if (constructor->IsJSFunction() &&
2519 JSFunction::cast(constructor)->initial_map() == map) { 2523 JSFunction::cast(constructor)->initial_map() == map) {
2520 // If we still have the original map, set in-object properties directly. 2524 // If we still have the original map, set in-object properties directly.
2521 regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, source); 2525 regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *source);
2522 // Both true and false are immovable immortal objects so no need for write 2526 // Both true and false are immovable immortal objects so no need for write
2523 // barrier. 2527 // barrier.
2524 regexp->InObjectPropertyAtPut( 2528 regexp->InObjectPropertyAtPut(
2525 JSRegExp::kGlobalFieldIndex, global, SKIP_WRITE_BARRIER); 2529 JSRegExp::kGlobalFieldIndex, *global, SKIP_WRITE_BARRIER);
2526 regexp->InObjectPropertyAtPut( 2530 regexp->InObjectPropertyAtPut(
2527 JSRegExp::kIgnoreCaseFieldIndex, ignoreCase, SKIP_WRITE_BARRIER); 2531 JSRegExp::kIgnoreCaseFieldIndex, *ignoreCase, SKIP_WRITE_BARRIER);
2528 regexp->InObjectPropertyAtPut( 2532 regexp->InObjectPropertyAtPut(
2529 JSRegExp::kMultilineFieldIndex, multiline, SKIP_WRITE_BARRIER); 2533 JSRegExp::kMultilineFieldIndex, *multiline, SKIP_WRITE_BARRIER);
2530 regexp->InObjectPropertyAtPut( 2534 regexp->InObjectPropertyAtPut(
2531 JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER); 2535 JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER);
2532 return regexp; 2536 return *regexp;
2533 } 2537 }
2534 2538
2535 // Map has changed, so use generic, but slower, method. 2539 // Map has changed, so use generic, but slower, method.
2536 PropertyAttributes final = 2540 PropertyAttributes final =
2537 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); 2541 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
2538 PropertyAttributes writable = 2542 PropertyAttributes writable =
2539 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); 2543 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
2540 Heap* heap = isolate->heap(); 2544 Handle<Object> zero(Smi::FromInt(0), isolate);
2541 MaybeObject* result; 2545 Factory* factory = isolate->factory();
2542 result = regexp->SetLocalPropertyIgnoreAttributes(heap->source_string(), 2546 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
2543 source, 2547 regexp, factory->source_string(), source, final));
2544 final); 2548 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
2545 // TODO(jkummerow): Turn these back into ASSERTs when we can be certain 2549 regexp, factory->global_string(), global, final));
2546 // that it never fires in Release mode in the wild. 2550 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
2547 CHECK(!result->IsFailure()); 2551 regexp, factory->ignore_case_string(), ignoreCase, final));
2548 result = regexp->SetLocalPropertyIgnoreAttributes(heap->global_string(), 2552 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
2549 global, 2553 regexp, factory->multiline_string(), multiline, final));
2550 final); 2554 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes(
2551 CHECK(!result->IsFailure()); 2555 regexp, factory->last_index_string(), zero, writable));
2552 result = 2556 return *regexp;
2553 regexp->SetLocalPropertyIgnoreAttributes(heap->ignore_case_string(),
2554 ignoreCase,
2555 final);
2556 CHECK(!result->IsFailure());
2557 result = regexp->SetLocalPropertyIgnoreAttributes(heap->multiline_string(),
2558 multiline,
2559 final);
2560 CHECK(!result->IsFailure());
2561 result =
2562 regexp->SetLocalPropertyIgnoreAttributes(heap->last_index_string(),
2563 Smi::FromInt(0),
2564 writable);
2565 CHECK(!result->IsFailure());
2566 USE(result);
2567 return regexp;
2568 } 2557 }
2569 2558
2570 2559
2571 RUNTIME_FUNCTION(MaybeObject*, Runtime_FinishArrayPrototypeSetup) { 2560 RUNTIME_FUNCTION(MaybeObject*, Runtime_FinishArrayPrototypeSetup) {
2572 HandleScope scope(isolate); 2561 HandleScope scope(isolate);
2573 ASSERT(args.length() == 1); 2562 ASSERT(args.length() == 1);
2574 CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0); 2563 CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
2575 // This is necessary to enable fast checks for absence of elements 2564 // This is necessary to enable fast checks for absence of elements
2576 // on Array.prototype and below. 2565 // on Array.prototype and below.
2577 prototype->set_elements(isolate->heap()->empty_fixed_array()); 2566 prototype->set_elements(isolate->heap()->empty_fixed_array());
(...skipping 2479 matching lines...) Expand 10 before | Expand all | Expand 10 after
5057 (attr != result.GetAttributes() || result.IsPropertyCallbacks())) { 5046 (attr != result.GetAttributes() || result.IsPropertyCallbacks())) {
5058 // New attributes - normalize to avoid writing to instance descriptor 5047 // New attributes - normalize to avoid writing to instance descriptor
5059 if (js_object->IsJSGlobalProxy()) { 5048 if (js_object->IsJSGlobalProxy()) {
5060 // Since the result is a property, the prototype will exist so 5049 // Since the result is a property, the prototype will exist so
5061 // we don't have to check for null. 5050 // we don't have to check for null.
5062 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); 5051 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
5063 } 5052 }
5064 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); 5053 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
5065 // Use IgnoreAttributes version since a readonly property may be 5054 // Use IgnoreAttributes version since a readonly property may be
5066 // overridden and SetProperty does not allow this. 5055 // overridden and SetProperty does not allow this.
5067 return js_object->SetLocalPropertyIgnoreAttributes(*name, 5056 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
5068 *obj_value, 5057 js_object, name, obj_value, attr);
5069 attr); 5058 RETURN_IF_EMPTY_HANDLE(isolate, result);
5059 return *result;
5070 } 5060 }
5071 5061
5072 return Runtime::ForceSetObjectProperty(isolate, 5062 return Runtime::ForceSetObjectProperty(isolate,
5073 js_object, 5063 js_object,
5074 name, 5064 name,
5075 obj_value, 5065 obj_value,
5076 attr); 5066 attr);
5077 } 5067 }
5078 5068
5079 5069
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
5245 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); 5235 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY);
5246 } 5236 }
5247 5237
5248 if (key->IsName()) { 5238 if (key->IsName()) {
5249 Handle<Name> name = Handle<Name>::cast(key); 5239 Handle<Name> name = Handle<Name>::cast(key);
5250 if (name->AsArrayIndex(&index)) { 5240 if (name->AsArrayIndex(&index)) {
5251 return js_object->SetElement( 5241 return js_object->SetElement(
5252 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); 5242 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY);
5253 } else { 5243 } else {
5254 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); 5244 if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
5255 return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr); 5245 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
5246 js_object, name, value, attr);
5247 RETURN_IF_EMPTY_HANDLE(isolate, result);
5248 return *result;
5256 } 5249 }
5257 } 5250 }
5258 5251
5259 // Call-back into JavaScript to convert the key to a string. 5252 // Call-back into JavaScript to convert the key to a string.
5260 bool has_pending_exception = false; 5253 bool has_pending_exception = false;
5261 Handle<Object> converted = 5254 Handle<Object> converted =
5262 Execution::ToString(isolate, key, &has_pending_exception); 5255 Execution::ToString(isolate, key, &has_pending_exception);
5263 if (has_pending_exception) return Failure::Exception(); 5256 if (has_pending_exception) return Failure::Exception();
5264 Handle<String> name = Handle<String>::cast(converted); 5257 Handle<String> name = Handle<String>::cast(converted);
5265 5258
5266 if (name->AsArrayIndex(&index)) { 5259 if (name->AsArrayIndex(&index)) {
5267 return js_object->SetElement( 5260 return js_object->SetElement(
5268 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); 5261 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY);
5269 } else { 5262 } else {
5270 return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr); 5263 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
5264 js_object, name, value, attr);
5265 RETURN_IF_EMPTY_HANDLE(isolate, result);
5266 return *result;
5271 } 5267 }
5272 } 5268 }
5273 5269
5274 5270
5275 MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate, 5271 MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate,
5276 Handle<JSReceiver> receiver, 5272 Handle<JSReceiver> receiver,
5277 Handle<Object> key, 5273 Handle<Object> key,
5278 JSReceiver::DeleteMode mode) { 5274 JSReceiver::DeleteMode mode) {
5279 HandleScope scope(isolate); 5275 HandleScope scope(isolate);
5280 5276
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
5463 debug->ClearStepOut(); 5459 debug->ClearStepOut();
5464 debug->FloodWithOneShot(callback); 5460 debug->FloodWithOneShot(callback);
5465 #endif // ENABLE_DEBUGGER_SUPPORT 5461 #endif // ENABLE_DEBUGGER_SUPPORT
5466 return isolate->heap()->undefined_value(); 5462 return isolate->heap()->undefined_value();
5467 } 5463 }
5468 5464
5469 5465
5470 // Set a local property, even if it is READ_ONLY. If the property does not 5466 // Set a local property, even if it is READ_ONLY. If the property does not
5471 // exist, it will be added with attributes NONE. 5467 // exist, it will be added with attributes NONE.
5472 RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) { 5468 RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) {
5473 SealHandleScope shs(isolate); 5469 HandleScope scope(isolate);
5474 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); 5470 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
5475 CONVERT_ARG_CHECKED(JSObject, object, 0); 5471 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5476 CONVERT_ARG_CHECKED(Name, name, 1); 5472 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
5473 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
5477 // Compute attributes. 5474 // Compute attributes.
5478 PropertyAttributes attributes = NONE; 5475 PropertyAttributes attributes = NONE;
5479 if (args.length() == 4) { 5476 if (args.length() == 4) {
5480 CONVERT_SMI_ARG_CHECKED(unchecked_value, 3); 5477 CONVERT_SMI_ARG_CHECKED(unchecked_value, 3);
5481 // Only attribute bits should be set. 5478 // Only attribute bits should be set.
5482 RUNTIME_ASSERT( 5479 RUNTIME_ASSERT(
5483 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); 5480 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
5484 attributes = static_cast<PropertyAttributes>(unchecked_value); 5481 attributes = static_cast<PropertyAttributes>(unchecked_value);
5485 } 5482 }
5486 5483 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
5487 return object-> 5484 object, name, value, attributes);
5488 SetLocalPropertyIgnoreAttributes(name, args[2], attributes); 5485 RETURN_IF_EMPTY_HANDLE(isolate, result);
5486 return *result;
5489 } 5487 }
5490 5488
5491 5489
5492 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) { 5490 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) {
5493 HandleScope scope(isolate); 5491 HandleScope scope(isolate);
5494 ASSERT(args.length() == 3); 5492 ASSERT(args.length() == 3);
5495 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); 5493 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
5496 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); 5494 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5497 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2); 5495 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
5498 JSReceiver::DeleteMode delete_mode = (strict_mode == kStrictMode) 5496 JSReceiver::DeleteMode delete_mode = (strict_mode == kStrictMode)
(...skipping 9177 matching lines...) Expand 10 before | Expand all | Expand 10 after
14676 // Handle last resort GC and make sure to allow future allocations 14674 // Handle last resort GC and make sure to allow future allocations
14677 // to grow the heap without causing GCs (if possible). 14675 // to grow the heap without causing GCs (if possible).
14678 isolate->counters()->gc_last_resort_from_js()->Increment(); 14676 isolate->counters()->gc_last_resort_from_js()->Increment();
14679 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 14677 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
14680 "Runtime::PerformGC"); 14678 "Runtime::PerformGC");
14681 } 14679 }
14682 } 14680 }
14683 14681
14684 14682
14685 } } // namespace v8::internal 14683 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698