| OLD | NEW |
| 1 // Copyright 2011 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 Handle<JSObject> object, | 369 Handle<JSObject> object, |
| 370 int index, | 370 int index, |
| 371 Handle<Map> transition, | 371 Handle<Map> transition, |
| 372 Register receiver_reg, | 372 Register receiver_reg, |
| 373 Register name_reg, | 373 Register name_reg, |
| 374 Register scratch, | 374 Register scratch, |
| 375 Label* miss_label) { | 375 Label* miss_label) { |
| 376 // r0 : value | 376 // r0 : value |
| 377 Label exit; | 377 Label exit; |
| 378 | 378 |
| 379 // Check that the receiver isn't a smi. | 379 // Check that the map of the object hasn't changed. |
| 380 __ JumpIfSmi(receiver_reg, miss_label); | 380 __ CheckMap(receiver_reg, scratch, Handle<Map>(object->map()), miss_label, |
| 381 | 381 DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); |
| 382 // Check that the map of the receiver hasn't changed. | |
| 383 __ ldr(scratch, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); | |
| 384 __ cmp(scratch, Operand(Handle<Map>(object->map()))); | |
| 385 __ b(ne, miss_label); | |
| 386 | 382 |
| 387 // Perform global security token check if needed. | 383 // Perform global security token check if needed. |
| 388 if (object->IsJSGlobalProxy()) { | 384 if (object->IsJSGlobalProxy()) { |
| 389 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); | 385 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); |
| 390 } | 386 } |
| 391 | 387 |
| 392 // Stub never generated for non-global objects that require access | 388 // Stub never generated for non-global objects that require access |
| 393 // checks. | 389 // checks. |
| 394 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 390 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
| 395 | 391 |
| (...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1012 StringDictionary::kNotFound); | 1008 StringDictionary::kNotFound); |
| 1013 | 1009 |
| 1014 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | 1010 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, |
| 1015 scratch1, scratch2); | 1011 scratch1, scratch2); |
| 1016 | 1012 |
| 1017 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1013 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
| 1018 reg = holder_reg; // From now on the object will be in holder_reg. | 1014 reg = holder_reg; // From now on the object will be in holder_reg. |
| 1019 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 1015 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
| 1020 } else { | 1016 } else { |
| 1021 Handle<Map> current_map(current->map()); | 1017 Handle<Map> current_map(current->map()); |
| 1022 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1018 __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK, |
| 1023 __ cmp(scratch1, Operand(current_map)); | 1019 ALLOW_ELEMENT_TRANSITION_MAPS); |
| 1024 // Branch on the result of the map check. | 1020 |
| 1025 __ b(ne, miss); | |
| 1026 // Check access rights to the global object. This has to happen after | 1021 // Check access rights to the global object. This has to happen after |
| 1027 // the map check so that we know that the object is actually a global | 1022 // the map check so that we know that the object is actually a global |
| 1028 // object. | 1023 // object. |
| 1029 if (current->IsJSGlobalProxy()) { | 1024 if (current->IsJSGlobalProxy()) { |
| 1030 __ CheckAccessGlobalProxy(reg, scratch2, miss); | 1025 __ CheckAccessGlobalProxy(reg, scratch2, miss); |
| 1031 } | 1026 } |
| 1032 reg = holder_reg; // From now on the object will be in holder_reg. | 1027 reg = holder_reg; // From now on the object will be in holder_reg. |
| 1033 | 1028 |
| 1034 if (heap()->InNewSpace(*prototype)) { | 1029 if (heap()->InNewSpace(*prototype)) { |
| 1035 // The prototype is in new space; we cannot store a reference to it | 1030 // The prototype is in new space; we cannot store a reference to it |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1046 } | 1041 } |
| 1047 | 1042 |
| 1048 // Go to the next object in the prototype chain. | 1043 // Go to the next object in the prototype chain. |
| 1049 current = prototype; | 1044 current = prototype; |
| 1050 } | 1045 } |
| 1051 | 1046 |
| 1052 // Log the check depth. | 1047 // Log the check depth. |
| 1053 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); | 1048 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); |
| 1054 | 1049 |
| 1055 // Check the holder map. | 1050 // Check the holder map. |
| 1056 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1051 __ CheckMap(reg, scratch1, Handle<Map>(current->map()), miss, |
| 1057 __ cmp(scratch1, Operand(Handle<Map>(current->map()))); | 1052 DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); |
| 1058 __ b(ne, miss); | |
| 1059 | 1053 |
| 1060 // Perform security check for access to the global object. | 1054 // Perform security check for access to the global object. |
| 1061 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 1055 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
| 1062 if (holder->IsJSGlobalProxy()) { | 1056 if (holder->IsJSGlobalProxy()) { |
| 1063 __ CheckAccessGlobalProxy(reg, scratch1, miss); | 1057 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
| 1064 } | 1058 } |
| 1065 | 1059 |
| 1066 // If we've skipped any global objects, it's not enough to verify that | 1060 // If we've skipped any global objects, it's not enough to verify that |
| 1067 // their maps haven't changed. We also need to check that the property | 1061 // their maps haven't changed. We also need to check that the property |
| 1068 // cell for the property is still empty. | 1062 // cell for the property is still empty. |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1143 __ Move(scratch3, Handle<Object>(callback->data())); | 1137 __ Move(scratch3, Handle<Object>(callback->data())); |
| 1144 } | 1138 } |
| 1145 __ Push(reg, scratch3, name_reg); | 1139 __ Push(reg, scratch3, name_reg); |
| 1146 __ mov(r0, sp); // r0 = Handle<String> | 1140 __ mov(r0, sp); // r0 = Handle<String> |
| 1147 | 1141 |
| 1148 const int kApiStackSpace = 1; | 1142 const int kApiStackSpace = 1; |
| 1149 FrameScope frame_scope(masm(), StackFrame::MANUAL); | 1143 FrameScope frame_scope(masm(), StackFrame::MANUAL); |
| 1150 __ EnterExitFrame(false, kApiStackSpace); | 1144 __ EnterExitFrame(false, kApiStackSpace); |
| 1151 | 1145 |
| 1152 // Create AccessorInfo instance on the stack above the exit frame with | 1146 // Create AccessorInfo instance on the stack above the exit frame with |
| 1153 // scratch2 (internal::Object **args_) as the data. | 1147 // scratch2 (internal::Object** args_) as the data. |
| 1154 __ str(scratch2, MemOperand(sp, 1 * kPointerSize)); | 1148 __ str(scratch2, MemOperand(sp, 1 * kPointerSize)); |
| 1155 __ add(r1, sp, Operand(1 * kPointerSize)); // r1 = AccessorInfo& | 1149 __ add(r1, sp, Operand(1 * kPointerSize)); // r1 = AccessorInfo& |
| 1156 | 1150 |
| 1157 const int kStackUnwindSpace = 4; | 1151 const int kStackUnwindSpace = 4; |
| 1158 Address getter_address = v8::ToCData<Address>(callback->getter()); | 1152 Address getter_address = v8::ToCData<Address>(callback->getter()); |
| 1159 ApiFunction fun(getter_address); | 1153 ApiFunction fun(getter_address); |
| 1160 ExternalReference ref = | 1154 ExternalReference ref = |
| 1161 ExternalReference(&fun, | 1155 ExternalReference(&fun, |
| 1162 ExternalReference::DIRECT_GETTER_CALL, | 1156 ExternalReference::DIRECT_GETTER_CALL, |
| 1163 masm()->isolate()); | 1157 masm()->isolate()); |
| (...skipping 1240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2404 GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2398 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
| 2405 GenerateLoadFunctionFromCell(cell, function, &miss); | 2399 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 2406 | 2400 |
| 2407 // Patch the receiver on the stack with the global proxy if | 2401 // Patch the receiver on the stack with the global proxy if |
| 2408 // necessary. | 2402 // necessary. |
| 2409 if (object->IsGlobalObject()) { | 2403 if (object->IsGlobalObject()) { |
| 2410 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); | 2404 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); |
| 2411 __ str(r3, MemOperand(sp, argc * kPointerSize)); | 2405 __ str(r3, MemOperand(sp, argc * kPointerSize)); |
| 2412 } | 2406 } |
| 2413 | 2407 |
| 2414 // Setup the context (function already in r1). | 2408 // Set up the context (function already in r1). |
| 2415 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 2409 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
| 2416 | 2410 |
| 2417 // Jump to the cached code (tail call). | 2411 // Jump to the cached code (tail call). |
| 2418 Counters* counters = masm()->isolate()->counters(); | 2412 Counters* counters = masm()->isolate()->counters(); |
| 2419 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); | 2413 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); |
| 2420 ParameterCount expected(function->shared()->formal_parameter_count()); | 2414 ParameterCount expected(function->shared()->formal_parameter_count()); |
| 2421 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2415 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
| 2422 ? CALL_AS_FUNCTION | 2416 ? CALL_AS_FUNCTION |
| 2423 : CALL_AS_METHOD; | 2417 : CALL_AS_METHOD; |
| 2424 // We call indirectly through the code field in the function to | 2418 // We call indirectly through the code field in the function to |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2465 Handle<AccessorInfo> callback, | 2459 Handle<AccessorInfo> callback, |
| 2466 Handle<String> name) { | 2460 Handle<String> name) { |
| 2467 // ----------- S t a t e ------------- | 2461 // ----------- S t a t e ------------- |
| 2468 // -- r0 : value | 2462 // -- r0 : value |
| 2469 // -- r1 : receiver | 2463 // -- r1 : receiver |
| 2470 // -- r2 : name | 2464 // -- r2 : name |
| 2471 // -- lr : return address | 2465 // -- lr : return address |
| 2472 // ----------------------------------- | 2466 // ----------------------------------- |
| 2473 Label miss; | 2467 Label miss; |
| 2474 | 2468 |
| 2475 // Check that the object isn't a smi. | |
| 2476 __ JumpIfSmi(r1, &miss); | |
| 2477 | |
| 2478 // Check that the map of the object hasn't changed. | 2469 // Check that the map of the object hasn't changed. |
| 2479 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); | 2470 __ CheckMap(r1, r3, Handle<Map>(object->map()), &miss, |
| 2480 __ cmp(r3, Operand(Handle<Map>(object->map()))); | 2471 DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); |
| 2481 __ b(ne, &miss); | |
| 2482 | 2472 |
| 2483 // Perform global security token check if needed. | 2473 // Perform global security token check if needed. |
| 2484 if (object->IsJSGlobalProxy()) { | 2474 if (object->IsJSGlobalProxy()) { |
| 2485 __ CheckAccessGlobalProxy(r1, r3, &miss); | 2475 __ CheckAccessGlobalProxy(r1, r3, &miss); |
| 2486 } | 2476 } |
| 2487 | 2477 |
| 2488 // Stub never generated for non-global objects that require access | 2478 // Stub never generated for non-global objects that require access |
| 2489 // checks. | 2479 // checks. |
| 2490 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 2480 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
| 2491 | 2481 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2513 Handle<JSObject> receiver, | 2503 Handle<JSObject> receiver, |
| 2514 Handle<String> name) { | 2504 Handle<String> name) { |
| 2515 // ----------- S t a t e ------------- | 2505 // ----------- S t a t e ------------- |
| 2516 // -- r0 : value | 2506 // -- r0 : value |
| 2517 // -- r1 : receiver | 2507 // -- r1 : receiver |
| 2518 // -- r2 : name | 2508 // -- r2 : name |
| 2519 // -- lr : return address | 2509 // -- lr : return address |
| 2520 // ----------------------------------- | 2510 // ----------------------------------- |
| 2521 Label miss; | 2511 Label miss; |
| 2522 | 2512 |
| 2523 // Check that the object isn't a smi. | |
| 2524 __ JumpIfSmi(r1, &miss); | |
| 2525 | |
| 2526 // Check that the map of the object hasn't changed. | 2513 // Check that the map of the object hasn't changed. |
| 2527 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); | 2514 __ CheckMap(r1, r3, Handle<Map>(receiver->map()), &miss, |
| 2528 __ cmp(r3, Operand(Handle<Map>(receiver->map()))); | 2515 DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); |
| 2529 __ b(ne, &miss); | |
| 2530 | 2516 |
| 2531 // Perform global security token check if needed. | 2517 // Perform global security token check if needed. |
| 2532 if (receiver->IsJSGlobalProxy()) { | 2518 if (receiver->IsJSGlobalProxy()) { |
| 2533 __ CheckAccessGlobalProxy(r1, r3, &miss); | 2519 __ CheckAccessGlobalProxy(r1, r3, &miss); |
| 2534 } | 2520 } |
| 2535 | 2521 |
| 2536 // Stub is never generated for non-global objects that require access | 2522 // Stub is never generated for non-global objects that require access |
| 2537 // checks. | 2523 // checks. |
| 2538 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); | 2524 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); |
| 2539 | 2525 |
| (...skipping 1686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4226 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 4212 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
| 4227 __ Jump(ic_miss, RelocInfo::CODE_TARGET); | 4213 __ Jump(ic_miss, RelocInfo::CODE_TARGET); |
| 4228 } | 4214 } |
| 4229 | 4215 |
| 4230 | 4216 |
| 4231 #undef __ | 4217 #undef __ |
| 4232 | 4218 |
| 4233 } } // namespace v8::internal | 4219 } } // namespace v8::internal |
| 4234 | 4220 |
| 4235 #endif // V8_TARGET_ARCH_ARM | 4221 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |