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

Side by Side Diff: src/a64/stub-cache-a64.cc

Issue 153923005: A64: Synchronize with r17525. (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/a64/macro-assembler-a64.cc ('k') | src/accessors.h » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 22 matching lines...) Expand all
33 #include "codegen.h" 33 #include "codegen.h"
34 #include "stub-cache.h" 34 #include "stub-cache.h"
35 35
36 namespace v8 { 36 namespace v8 {
37 namespace internal { 37 namespace internal {
38 38
39 39
40 #define __ ACCESS_MASM(masm) 40 #define __ ACCESS_MASM(masm)
41 41
42 42
43 // Helper function used to check that the dictionary doesn't contain 43 void StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm,
44 // the property. This function may return false negatives, so miss_label 44 Label* miss_label,
45 // must always call a backup property check that is complete. 45 Register receiver,
46 // This function is safe to call if the receiver has fast properties. 46 Handle<Name> name,
47 // Name must be unique and receiver must be a heap object. 47 Register scratch0,
48 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, 48 Register scratch1) {
49 Label* miss_label, 49 ASSERT(!AreAliased(receiver, scratch0, scratch1));
50 Register receiver,
51 Handle<Name> name,
52 Register scratch0,
53 Register scratch1) {
54 ASSERT(!AreAliased(scratch0, scratch1));
55 ASSERT(name->IsUniqueName()); 50 ASSERT(name->IsUniqueName());
56 Counters* counters = masm->isolate()->counters(); 51 Counters* counters = masm->isolate()->counters();
57 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); 52 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
58 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 53 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
59 54
60 Label done; 55 Label done;
61 56
62 const int kInterceptorOrAccessCheckNeededMask = 57 const int kInterceptorOrAccessCheckNeededMask =
63 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 58 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
64 59
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 // LoadIC::GenerateFunctionPrototype, where receiver is x0. So we explicitly 366 // LoadIC::GenerateFunctionPrototype, where receiver is x0. So we explicitly
372 // move the result in x0. 367 // move the result in x0.
373 __ Mov(x0, scratch1); 368 __ Mov(x0, scratch1);
374 __ Ret(); 369 __ Ret();
375 } 370 }
376 371
377 372
378 // Generate code to check that a global property cell is empty. Create 373 // Generate code to check that a global property cell is empty. Create
379 // the property cell at compilation time if no cell exists for the 374 // the property cell at compilation time if no cell exists for the
380 // property. 375 // property.
381 static void GenerateCheckPropertyCell(MacroAssembler* masm, 376 void StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm,
382 Handle<GlobalObject> global, 377 Handle<JSGlobalObject> global,
383 Handle<Name> name, 378 Handle<Name> name,
384 Register scratch, 379 Register scratch,
385 Register the_hole, 380 Label* miss) {
386 Label* miss) { 381 Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
387 Handle<Cell> cell = GlobalObject::EnsurePropertyCell(global, name);
388 ASSERT(cell->value()->IsTheHole()); 382 ASSERT(cell->value()->IsTheHole());
389 __ Mov(scratch, Operand(cell)); 383 __ Mov(scratch, Operand(cell));
390 __ Ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); 384 __ Ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
391 __ Cmp(scratch, the_hole); 385 __ JumpIfNotRoot(scratch, Heap::kTheHoleValueRootIndex, miss);
392 __ B(ne, miss);
393 } 386 }
394 387
395 388
396 void StoreStubCompiler::GenerateNegativeHolderLookup( 389 void StoreStubCompiler::GenerateNegativeHolderLookup(
397 MacroAssembler* masm, 390 MacroAssembler* masm,
398 Handle<JSObject> holder, 391 Handle<JSObject> holder,
399 Register holder_reg, 392 Register holder_reg,
400 Handle<Name> name, 393 Handle<Name> name,
401 Label* miss) { 394 Label* miss) {
402 if (holder->IsJSGlobalObject()) { 395 if (holder->IsJSGlobalObject()) {
403 __ LoadRoot(scratch2(), Heap::kTheHoleValueRootIndex);
404 GenerateCheckPropertyCell( 396 GenerateCheckPropertyCell(
405 masm, Handle<GlobalObject>::cast(holder), name, 397 masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss);
406 scratch1(), scratch2(), miss);
407 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { 398 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
408 GenerateDictionaryNegativeLookup( 399 GenerateDictionaryNegativeLookup(
409 masm, miss, holder_reg, name, scratch1(), scratch2()); 400 masm, miss, holder_reg, name, scratch1(), scratch2());
410 } 401 }
411 } 402 }
412 403
413 404
414 // Generate StoreTransition code, value is passed in x0 register. 405 // Generate StoreTransition code, value is passed in x0 register.
415 // When leaving generated code after success, the receiver_reg and storage_reg 406 // When leaving generated code after success, the receiver_reg and storage_reg
416 // may be clobbered. Upon branch to miss_label, the receiver and name registers 407 // may be clobbered. Upon branch to miss_label, the receiver and name registers
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 697 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
707 Label* label, 698 Label* label,
708 Handle<Name> name) { 699 Handle<Name> name) {
709 if (!label->is_unused()) { 700 if (!label->is_unused()) {
710 __ Bind(label); 701 __ Bind(label);
711 __ Mov(this->name(), Operand(name)); 702 __ Mov(this->name(), Operand(name));
712 } 703 }
713 } 704 }
714 705
715 706
716 // Calls GenerateCheckPropertyCell for each global object in the prototype chain 707 void StubCompiler::GenerateCheckPropertyCells(MacroAssembler* masm,
717 // from object to (but not including) holder. 708 Handle<JSObject> object,
718 static void GenerateCheckPropertyCells(MacroAssembler* masm, 709 Handle<JSObject> holder,
719 Handle<JSObject> object, 710 Handle<Name> name,
720 Handle<JSObject> holder, 711 Register scratch1,
721 Handle<Name> name, 712 Label* miss) {
722 Register scratch1,
723 Register scratch2,
724 Label* miss) {
725 bool the_hole_is_loaded = false;
726 Handle<JSObject> current = object; 713 Handle<JSObject> current = object;
727 while (!current.is_identical_to(holder)) { 714 while (!current.is_identical_to(holder)) {
728 if (current->IsGlobalObject()) { 715 if (current->IsJSGlobalObject()) {
729 if (!the_hole_is_loaded) { 716 // TODO(all): GenerateCheckPropertyCell loads the hole (root value) every
730 __ LoadRoot(scratch2, Heap::kTheHoleValueRootIndex); 717 // time. Hoist that out, and load it once at the start.
731 the_hole_is_loaded = true;
732 }
733 GenerateCheckPropertyCell(masm, 718 GenerateCheckPropertyCell(masm,
734 Handle<GlobalObject>::cast(current), 719 Handle<JSGlobalObject>::cast(current),
735 name, 720 name,
736 scratch1, 721 scratch1,
737 scratch2,
738 miss); 722 miss);
739 } 723 }
740 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); 724 current = Handle<JSObject>(JSObject::cast(current->GetPrototype()));
741 } 725 }
742 } 726 }
743 727
744 728
745 // The function to called must be passed in x1. 729 // The function to called must be passed in x1.
746 static void GenerateCallFunction(MacroAssembler* masm, 730 static void GenerateCallFunction(MacroAssembler* masm,
747 Handle<Object> object, 731 Handle<Object> object,
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
1288 1272
1289 // Perform security check for access to the global object. 1273 // Perform security check for access to the global object.
1290 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 1274 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
1291 if (holder->IsJSGlobalProxy()) { 1275 if (holder->IsJSGlobalProxy()) {
1292 __ CheckAccessGlobalProxy(reg, scratch1, miss); 1276 __ CheckAccessGlobalProxy(reg, scratch1, miss);
1293 } 1277 }
1294 1278
1295 // If we've skipped any global objects, it's not enough to verify that 1279 // If we've skipped any global objects, it's not enough to verify that
1296 // their maps haven't changed. We also need to check that the property 1280 // their maps haven't changed. We also need to check that the property
1297 // cell for the property is still empty. 1281 // cell for the property is still empty.
1298 GenerateCheckPropertyCells(masm(), object, holder, name, 1282 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1299 scratch1, scratch2, miss);
1300 1283
1301 // Return the register containing the holder. 1284 // Return the register containing the holder.
1302 return reg; 1285 return reg;
1303 } 1286 }
1304 1287
1305 1288
1306 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, 1289 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name,
1307 Label* success, 1290 Label* success,
1308 Label* miss) { 1291 Label* miss) {
1309 if (!miss->is_unused()) { 1292 if (!miss->is_unused()) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1366 __ Ldr(scratch2(), FieldMemOperand(pointer, kValueOffset)); 1349 __ Ldr(scratch2(), FieldMemOperand(pointer, kValueOffset));
1367 __ Cmp(scratch2(), Operand(callback)); 1350 __ Cmp(scratch2(), Operand(callback));
1368 __ B(ne, &miss); 1351 __ B(ne, &miss);
1369 } 1352 }
1370 1353
1371 HandlerFrontendFooter(name, success, &miss); 1354 HandlerFrontendFooter(name, success, &miss);
1372 return reg; 1355 return reg;
1373 } 1356 }
1374 1357
1375 1358
1376 void LoadStubCompiler::NonexistentHandlerFrontend(Handle<JSObject> object,
1377 Handle<JSObject> last,
1378 Handle<Name> name,
1379 Label* success,
1380 Handle<GlobalObject> global) {
1381 Label miss;
1382
1383 HandlerFrontendHeader(object, receiver(), last, name, &miss);
1384
1385 // If the last object in the prototype chain is a global object,
1386 // check that the global property cell is empty.
1387 if (!global.is_null()) {
1388 GenerateCheckPropertyCell(masm(), global, name,
1389 scratch1(), scratch2(), &miss);
1390 }
1391
1392 HandlerFrontendFooter(name, success, &miss);
1393 }
1394
1395
1396 void LoadStubCompiler::GenerateLoadField(Register reg, 1359 void LoadStubCompiler::GenerateLoadField(Register reg,
1397 Handle<JSObject> holder, 1360 Handle<JSObject> holder,
1398 PropertyIndex field, 1361 PropertyIndex field,
1399 Representation representation) { 1362 Representation representation) {
1400 __ Mov(receiver(), reg); 1363 __ Mov(receiver(), reg);
1401 if (kind() == Code::LOAD_IC) { 1364 if (kind() == Code::LOAD_IC) {
1402 LoadFieldStub stub(field.is_inobject(holder), 1365 LoadFieldStub stub(field.is_inobject(holder),
1403 field.translate(holder), 1366 field.translate(holder),
1404 representation); 1367 representation);
1405 GenerateTailCall(masm(), stub.GetCode(isolate())); 1368 GenerateTailCall(masm(), stub.GetCode(isolate()));
(...skipping 1592 matching lines...) Expand 10 before | Expand all | Expand 10 after
2998 2961
2999 // Return the generated code. 2962 // Return the generated code.
3000 return GetCode(kind(), Code::INTERCEPTOR, name); 2963 return GetCode(kind(), Code::INTERCEPTOR, name);
3001 } 2964 }
3002 2965
3003 2966
3004 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( 2967 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
3005 Handle<JSObject> object, 2968 Handle<JSObject> object,
3006 Handle<JSObject> last, 2969 Handle<JSObject> last,
3007 Handle<Name> name, 2970 Handle<Name> name,
3008 Handle<GlobalObject> global) { 2971 Handle<JSGlobalObject> global) {
3009 Label success; 2972 Label success;
3010 NonexistentHandlerFrontend(object, last, name, &success, global); 2973 NonexistentHandlerFrontend(object, last, name, &success, global);
3011 2974
3012 __ Bind(&success); 2975 __ Bind(&success);
3013 // Return undefined if maps of the full prototype chain are still the 2976 // Return undefined if maps of the full prototype chain are still the
3014 // same and no global property with this name contains a value. 2977 // same and no global property with this name contains a value.
3015 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); 2978 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
3016 __ Ret(); 2979 __ Ret();
3017 2980
3018 // Return the generated code. 2981 // Return the generated code.
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
3265 3228
3266 // Miss case, call the runtime. 3229 // Miss case, call the runtime.
3267 __ Bind(&miss_force_generic); 3230 __ Bind(&miss_force_generic);
3268 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); 3231 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3269 } 3232 }
3270 3233
3271 3234
3272 } } // namespace v8::internal 3235 } } // namespace v8::internal
3273 3236
3274 #endif // V8_TARGET_ARCH_A64 3237 #endif // V8_TARGET_ARCH_A64
OLDNEW
« no previous file with comments | « src/a64/macro-assembler-a64.cc ('k') | src/accessors.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698