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

Side by Side Diff: src/runtime.cc

Issue 153773002: A64: Synchronize with r16679. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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/runtime.h ('k') | src/runtime-profiler.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 8563 matching lines...) Expand 10 before | Expand all | Expand 10 after
8574 8574
8575 8575
8576 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationCount) { 8576 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOptimizationCount) {
8577 HandleScope scope(isolate); 8577 HandleScope scope(isolate);
8578 ASSERT(args.length() == 1); 8578 ASSERT(args.length() == 1);
8579 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 8579 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8580 return Smi::FromInt(function->shared()->opt_count()); 8580 return Smi::FromInt(function->shared()->opt_count());
8581 } 8581 }
8582 8582
8583 8583
8584 static bool IsSuitableForOnStackReplacement(Isolate* isolate,
8585 Handle<JSFunction> function,
8586 Handle<Code> unoptimized) {
8587 // Keep track of whether we've succeeded in optimizing.
8588 if (!unoptimized->optimizable()) return false;
8589 // If we are trying to do OSR when there are already optimized
8590 // activations of the function, it means (a) the function is directly or
8591 // indirectly recursive and (b) an optimized invocation has been
8592 // deoptimized so that we are currently in an unoptimized activation.
8593 // Check for optimized activations of this function.
8594 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
8595 JavaScriptFrame* frame = it.frame();
8596 if (frame->is_optimized() && frame->function() == *function) return false;
8597 }
8598
8599 return true;
8600 }
8601
8602
8584 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) { 8603 RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
8585 HandleScope scope(isolate); 8604 HandleScope scope(isolate);
8586 ASSERT(args.length() == 1); 8605 ASSERT(args.length() == 2);
8587 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 8606 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8607 CONVERT_NUMBER_CHECKED(uint32_t, pc_offset, Uint32, args[1]);
8608 Handle<Code> unoptimized(function->shared()->code(), isolate);
8609
8610 #ifdef DEBUG
8611 JavaScriptFrameIterator it(isolate);
8612 JavaScriptFrame* frame = it.frame();
8613 ASSERT_EQ(frame->function(), *function);
8614 ASSERT_EQ(frame->LookupCode(), *unoptimized);
8615 ASSERT(unoptimized->contains(frame->pc()));
8616
8617 ASSERT(pc_offset ==
8618 static_cast<uint32_t>(frame->pc() - unoptimized->instruction_start()));
8619 #endif // DEBUG
8588 8620
8589 // We're not prepared to handle a function with arguments object. 8621 // We're not prepared to handle a function with arguments object.
8590 ASSERT(!function->shared()->uses_arguments()); 8622 ASSERT(!function->shared()->uses_arguments());
8591 8623
8592 // If the optimization attempt succeeds, return the code object which 8624 Handle<Code> result = Handle<Code>::null();
8593 // the unoptimized code can jump into. 8625 BailoutId ast_id = BailoutId::None();
8594 Handle<Code> code = 8626
8595 (FLAG_concurrent_recompilation && FLAG_concurrent_osr) 8627 if (FLAG_concurrent_recompilation && FLAG_concurrent_osr) {
8596 ? Compiler::CompileForConcurrentOSR(function) 8628 if (isolate->optimizing_compiler_thread()->
8597 : Compiler::CompileForOnStackReplacement(function); 8629 IsQueuedForOSR(function, pc_offset)) {
8598 if (!code.is_null()) { 8630 // Still waiting for the optimizing compiler thread to finish. Carry on.
8599 #if DEBUG 8631 if (FLAG_trace_osr) {
8600 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION); 8632 PrintF("[COSR - polling recompile tasks for ");
8633 function->PrintName();
8634 PrintF("]\n");
8635 }
8636 return NULL;
8637 }
8638
8639 OptimizingCompiler* compiler = isolate->optimizing_compiler_thread()->
8640 FindReadyOSRCandidate(function, pc_offset);
8641
8642 if (compiler == NULL) {
8643 if (IsSuitableForOnStackReplacement(isolate, function, unoptimized) &&
8644 Compiler::RecompileConcurrent(function, pc_offset)) {
8645 if (function->IsMarkedForLazyRecompilation() ||
8646 function->IsMarkedForConcurrentRecompilation()) {
8647 // Prevent regular recompilation if we queue this for OSR.
8648 // TODO(yangguo): remove this as soon as OSR becomes one-shot.
8649 function->ReplaceCode(function->shared()->code());
8650 }
8651 return NULL;
8652 }
8653 // Fall through to the end in case of failure.
8654 } else {
8655 // TODO(titzer): don't install the OSR code into the function.
8656 ast_id = compiler->info()->osr_ast_id();
8657 result = Compiler::InstallOptimizedCode(compiler);
8658 }
8659 } else if (IsSuitableForOnStackReplacement(isolate, function, unoptimized)) {
8660 ast_id = unoptimized->TranslatePcOffsetToAstId(pc_offset);
8661 ASSERT(!ast_id.IsNone());
8662 if (FLAG_trace_osr) {
8663 PrintF("[OSR - replacing at AST id %d in ", ast_id.ToInt());
8664 function->PrintName();
8665 PrintF("]\n");
8666 }
8667 // Attempt OSR compilation.
8668 result = JSFunction::CompileOsr(function, ast_id, CLEAR_EXCEPTION);
8669 }
8670
8671 // Revert the patched interrupt now, regardless of whether OSR succeeds.
8672 Deoptimizer::RevertInterruptCode(isolate, *unoptimized);
8673
8674 // Check whether we ended up with usable optimized code.
8675 if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) {
8601 DeoptimizationInputData* data = 8676 DeoptimizationInputData* data =
8602 DeoptimizationInputData::cast(code->deoptimization_data()); 8677 DeoptimizationInputData::cast(result->deoptimization_data());
8603 ASSERT(!BailoutId(data->OsrAstId()->value()).IsNone()); 8678
8604 #endif 8679 if (data->OsrPcOffset()->value() >= 0) {
8605 // TODO(titzer): this is a massive hack to make the deopt counts 8680 ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
8606 // match. Fix heuristics for reenabling optimizations! 8681 if (FLAG_trace_osr) {
8607 function->shared()->increment_deopt_count(); 8682 PrintF("[OSR - entry at AST id %d, offset %d in optimized code]\n",
8608 return *code; 8683 ast_id.ToInt(), data->OsrPcOffset()->value());
8609 } else { 8684 }
8610 if (function->IsMarkedForLazyRecompilation() || 8685 // TODO(titzer): this is a massive hack to make the deopt counts
8611 function->IsMarkedForConcurrentRecompilation()) { 8686 // match. Fix heuristics for reenabling optimizations!
8612 function->ReplaceCode(function->shared()->code()); 8687 function->shared()->increment_deopt_count();
8688 return *result;
8613 } 8689 }
8614 return NULL;
8615 } 8690 }
8691
8692 if (FLAG_trace_osr) {
8693 PrintF("[OSR - optimization failed for ");
8694 function->PrintName();
8695 PrintF("]\n");
8696 }
8697
8698 if (function->IsMarkedForLazyRecompilation() ||
8699 function->IsMarkedForConcurrentRecompilation()) {
8700 function->ReplaceCode(function->shared()->code());
8701 }
8702 return NULL;
8616 } 8703 }
8617 8704
8618 8705
8619 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAllocationTimeout) { 8706 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAllocationTimeout) {
8620 SealHandleScope shs(isolate); 8707 SealHandleScope shs(isolate);
8621 ASSERT(args.length() == 2); 8708 ASSERT(args.length() == 2);
8622 #ifdef DEBUG 8709 #ifdef DEBUG
8623 CONVERT_SMI_ARG_CHECKED(interval, 0); 8710 CONVERT_SMI_ARG_CHECKED(interval, 0);
8624 CONVERT_SMI_ARG_CHECKED(timeout, 1); 8711 CONVERT_SMI_ARG_CHECKED(timeout, 1);
8625 isolate->heap()->set_allocation_timeout(timeout); 8712 isolate->heap()->set_allocation_timeout(timeout);
(...skipping 4317 matching lines...) Expand 10 before | Expand all | Expand 10 after
12943 NULL, 13030 NULL,
12944 0); 13031 0);
12945 13032
12946 // Allocate an array to hold the result. 13033 // Allocate an array to hold the result.
12947 Object* object; 13034 Object* object;
12948 { MaybeObject* maybe_object = heap->AllocateFixedArray(count); 13035 { MaybeObject* maybe_object = heap->AllocateFixedArray(count);
12949 if (!maybe_object->ToObject(&object)) return maybe_object; 13036 if (!maybe_object->ToObject(&object)) return maybe_object;
12950 } 13037 }
12951 FixedArray* instances = FixedArray::cast(object); 13038 FixedArray* instances = FixedArray::cast(object);
12952 13039
12953 ASSERT(HEAP->IsHeapIterable()); 13040 ASSERT(isolate->heap()->IsHeapIterable());
12954 // Fill the referencing objects. 13041 // Fill the referencing objects.
12955 HeapIterator heap_iterator2(heap); 13042 HeapIterator heap_iterator2(heap);
12956 count = DebugConstructedBy(&heap_iterator2, 13043 count = DebugConstructedBy(&heap_iterator2,
12957 constructor, 13044 constructor,
12958 max_references, 13045 max_references,
12959 instances, 13046 instances,
12960 count); 13047 count);
12961 13048
12962 // Return result as JS array. 13049 // Return result as JS array.
12963 Object* result; 13050 Object* result;
(...skipping 1447 matching lines...) Expand 10 before | Expand all | Expand 10 after
14411 14498
14412 RUNTIME_FUNCTION(MaybeObject*, Runtime_HaveSameMap) { 14499 RUNTIME_FUNCTION(MaybeObject*, Runtime_HaveSameMap) {
14413 SealHandleScope shs(isolate); 14500 SealHandleScope shs(isolate);
14414 ASSERT(args.length() == 2); 14501 ASSERT(args.length() == 2);
14415 CONVERT_ARG_CHECKED(JSObject, obj1, 0); 14502 CONVERT_ARG_CHECKED(JSObject, obj1, 0);
14416 CONVERT_ARG_CHECKED(JSObject, obj2, 1); 14503 CONVERT_ARG_CHECKED(JSObject, obj2, 1);
14417 return isolate->heap()->ToBoolean(obj1->map() == obj2->map()); 14504 return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
14418 } 14505 }
14419 14506
14420 14507
14508 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsAccessCheckNeeded) {
14509 SealHandleScope shs(isolate);
14510 ASSERT(args.length() == 1);
14511 CONVERT_ARG_CHECKED(HeapObject, obj, 0);
14512 return isolate->heap()->ToBoolean(obj->IsAccessCheckNeeded());
14513 }
14514
14515
14421 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsObserved) { 14516 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsObserved) {
14422 SealHandleScope shs(isolate); 14517 SealHandleScope shs(isolate);
14423 ASSERT(args.length() == 1); 14518 ASSERT(args.length() == 1);
14424 14519
14425 if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value(); 14520 if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value();
14426 JSReceiver* obj = JSReceiver::cast(args[0]); 14521 JSReceiver* obj = JSReceiver::cast(args[0]);
14427 if (obj->IsJSGlobalProxy()) { 14522 if (obj->IsJSGlobalProxy()) {
14428 Object* proto = obj->GetPrototype(); 14523 Object* proto = obj->GetPrototype();
14429 if (proto->IsNull()) return isolate->heap()->false_value(); 14524 if (proto->IsNull()) return isolate->heap()->false_value();
14430 ASSERT(proto->IsJSGlobalObject()); 14525 ASSERT(proto->IsJSGlobalObject());
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
14488 ASSERT(args.length() == 1); 14583 ASSERT(args.length() == 1);
14489 Object* object = args[0]; 14584 Object* object = args[0];
14490 if (object->IsJSGlobalProxy()) { 14585 if (object->IsJSGlobalProxy()) {
14491 object = object->GetPrototype(isolate); 14586 object = object->GetPrototype(isolate);
14492 if (object->IsNull()) return isolate->heap()->undefined_value(); 14587 if (object->IsNull()) return isolate->heap()->undefined_value();
14493 } 14588 }
14494 return object; 14589 return object;
14495 } 14590 }
14496 14591
14497 14592
14593 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsAccessAllowedForObserver) {
14594 HandleScope scope(isolate);
14595 ASSERT(args.length() == 3);
14596 CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
14597 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1);
14598 ASSERT(object->IsAccessCheckNeeded());
14599 Handle<Object> key = args.at<Object>(2);
14600 SaveContext save(isolate);
14601 isolate->set_context(observer->context());
14602 if (!isolate->MayNamedAccess(*object, isolate->heap()->undefined_value(),
14603 v8::ACCESS_KEYS)) {
14604 return isolate->heap()->false_value();
14605 }
14606 bool access_allowed = false;
14607 uint32_t index = 0;
14608 if (key->ToArrayIndex(&index) ||
14609 (key->IsString() && String::cast(*key)->AsArrayIndex(&index))) {
14610 access_allowed =
14611 isolate->MayIndexedAccess(*object, index, v8::ACCESS_GET) &&
14612 isolate->MayIndexedAccess(*object, index, v8::ACCESS_HAS);
14613 } else {
14614 access_allowed = isolate->MayNamedAccess(*object, *key, v8::ACCESS_GET) &&
14615 isolate->MayNamedAccess(*object, *key, v8::ACCESS_HAS);
14616 }
14617 return isolate->heap()->ToBoolean(access_allowed);
14618 }
14619
14620
14498 static MaybeObject* ArrayConstructorCommon(Isolate* isolate, 14621 static MaybeObject* ArrayConstructorCommon(Isolate* isolate,
14499 Handle<JSFunction> constructor, 14622 Handle<JSFunction> constructor,
14500 Handle<Object> type_info, 14623 Handle<Object> type_info,
14501 Arguments* caller_args) { 14624 Arguments* caller_args) {
14502 bool holey = false; 14625 bool holey = false;
14503 bool can_use_type_feedback = true; 14626 bool can_use_type_feedback = true;
14504 if (caller_args->length() == 1) { 14627 if (caller_args->length() == 1) {
14505 Object* argument_one = (*caller_args)[0]; 14628 Object* argument_one = (*caller_args)[0];
14506 if (argument_one->IsSmi()) { 14629 if (argument_one->IsSmi()) {
14507 int value = Smi::cast(argument_one)->value(); 14630 int value = Smi::cast(argument_one)->value();
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
14676 // Handle last resort GC and make sure to allow future allocations 14799 // Handle last resort GC and make sure to allow future allocations
14677 // to grow the heap without causing GCs (if possible). 14800 // to grow the heap without causing GCs (if possible).
14678 isolate->counters()->gc_last_resort_from_js()->Increment(); 14801 isolate->counters()->gc_last_resort_from_js()->Increment();
14679 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 14802 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
14680 "Runtime::PerformGC"); 14803 "Runtime::PerformGC");
14681 } 14804 }
14682 } 14805 }
14683 14806
14684 14807
14685 } } // namespace v8::internal 14808 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/runtime-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698