mirror of
				https://github.com/tc39/test262.git
				synced 2025-10-31 11:44:31 +01:00 
			
		
		
		
	sourceRevisionAtLastExport: 33f2fb0e53d135f0ee17cfccd9d993eb2a6f47de targetRevisionAtLastExport: 31340cbd9add103f586d501b0c3354b7b182abc0
		
			
				
	
	
		
			69 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			69 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // Copyright 2017 the V8 project authors. All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style license that can be
 | |
| // found in the LICENSE file.
 | |
| 
 | |
| // Flags: --allow-natives-syntax --expose-gc
 | |
| 
 | |
| function Data() {
 | |
| }
 | |
| Data.prototype = { x: 1 };
 | |
| 
 | |
| function TriggerDeopt() {
 | |
|   Data.prototype = { x: 2 };
 | |
| }
 | |
| 
 | |
| function TestDontSelfHealWithDeoptedCode(run_unoptimized, ClosureFactory) {
 | |
|   // Create some function closures which don't have
 | |
|   // optimized code.
 | |
|   var unoptimized_closure = ClosureFactory();
 | |
|   if (run_unoptimized) {
 | |
|     unoptimized_closure();
 | |
|   }
 | |
| 
 | |
|   // Run and optimize the code (do this in a separate function
 | |
|   // so that the closure doesn't leak in a dead register).
 | |
|   (() => {
 | |
|     var optimized_closure = ClosureFactory();
 | |
|     // Use .call to avoid the CallIC retaining the JSFunction in the
 | |
|     // feedback vector via a weak map, which would mean it wouldn't be
 | |
|     // collected in the minor gc below.
 | |
|     optimized_closure.call(undefined);
 | |
|     %OptimizeFunctionOnNextCall(optimized_closure);
 | |
|     optimized_closure.call(undefined);
 | |
|   })();
 | |
| 
 | |
|   // Optimize a dummy function, just so it gets linked into the
 | |
|   // Contexts optimized_functions list head, which is in the old
 | |
|   // space, and the link from to the optimized_closure's JSFunction
 | |
|   // moves to the inline link in dummy's JSFunction in the new space,
 | |
|   // otherwise optimized_closure's JSFunction will be retained by the
 | |
|   // old->new remember set.
 | |
|   (() => {
 | |
|     var dummy = function() { return 1; };
 | |
|     %OptimizeFunctionOnNextCall(dummy);
 | |
|     dummy();
 | |
|   })();
 | |
| 
 | |
|   // GC the optimized closure with a minor GC - the optimized
 | |
|   // code will remain in the feedback vector.
 | |
|   gc(true);
 | |
| 
 | |
|   // Trigger deoptimization by changing the prototype of Data. This
 | |
|   // will mark the code for deopt, but since no live JSFunction has
 | |
|   // optimized code, we won't clear the feedback vector.
 | |
|   TriggerDeopt();
 | |
| 
 | |
|   // Call pre-existing functions, these will try to self-heal with the
 | |
|   // optimized code in the feedback vector op, but should bail-out
 | |
|   // since the code is marked for deoptimization.
 | |
|   unoptimized_closure();
 | |
| }
 | |
| 
 | |
| // Run with the unoptimized closure both uncomplied and compiled for the
 | |
| // interpreter initially, to test self healing on both CompileLazy and
 | |
| // the InterpreterEntryTrampoline respectively.
 | |
| TestDontSelfHealWithDeoptedCode(false,
 | |
|         () => { return () => { return new Data() }});
 | |
| TestDontSelfHealWithDeoptedCode(true,
 | |
|         () => { return () => { return new Data() }});
 |