Tcl Source Code

Check-in [3b589e9ee8]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:A different technique to more precisely identify the optimization case.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dgp-list-simplify
Files: files | file ages | folders
SHA1: 3b589e9ee80d274391ea4ab44d5aa7385233fe0b
User & Date: dgp 2011-05-09 13:26:09
Context
2011-05-09
13:46
Remove the old implementation. Closed-Leaf check-in: a040b3dde3 user: dgp tags: dgp-list-simplify
13:26
A different technique to more precisely identify the optimization case. check-in: 3b589e9ee8 user: dgp tags: dgp-list-simplify
2011-05-05
18:00
Disable all the special case code in place to prevent allocation of a List struct for empty lists as... check-in: cc113f7cfe user: dgp tags: dgp-list-simplify
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tclListObj.c.

456
457
458
459
460
461
462
463
464

465
466
467
468
469
470
471
472
473
474
475





476
477
478
479
480
481
482
483
484
485
486
487
				 * referenced by objv. */
    Tcl_Obj ***objvPtr)		/* Where to store the pointer to an array of
				 * pointers to the list's objects. */
{
    register List *listRepPtr;

    if (listPtr->typePtr != &tclListType) {
	int result, length;
#if 0

	/*
	 * Don't get the string version of a dictionary; that transformation
	 * is not lossy, but is expensive.
	 */

	if (listPtr->typePtr == &tclDictType) {
	    (void) Tcl_DictObjSize(NULL, listPtr, &length);
	} else {
	    (void) TclGetStringFromObj(listPtr, &length);
	}
	if (!length) {





	    *objcPtr = 0;
	    *objvPtr = NULL;
	    return TCL_OK;
	}
#endif
	result = SetListFromAny(interp, listPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }
    listRepPtr = ListRepPtr(listPtr);
    *objcPtr = listRepPtr->elemCount;







<

>











>
>
>
>
>




<







456
457
458
459
460
461
462

463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484

485
486
487
488
489
490
491
				 * referenced by objv. */
    Tcl_Obj ***objvPtr)		/* Where to store the pointer to an array of
				 * pointers to the list's objects. */
{
    register List *listRepPtr;

    if (listPtr->typePtr != &tclListType) {

#if 0
	int result, length;
	/*
	 * Don't get the string version of a dictionary; that transformation
	 * is not lossy, but is expensive.
	 */

	if (listPtr->typePtr == &tclDictType) {
	    (void) Tcl_DictObjSize(NULL, listPtr, &length);
	} else {
	    (void) TclGetStringFromObj(listPtr, &length);
	}
	if (!length) {
#else
	int result;

	if (listPtr->bytes == tclEmptyStringRep) {
#endif
	    *objcPtr = 0;
	    *objvPtr = NULL;
	    return TCL_OK;
	}

	result = SetListFromAny(interp, listPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }
    listRepPtr = ListRepPtr(listPtr);
    *objcPtr = listRepPtr->elemCount;
583
584
585
586
587
588
589
590
591

592
593
594
595
596
597





598
599
600
601
602
603
604
605
606
607
608
    register Tcl_Obj **elemPtrs;
    int numElems, numRequired, newMax, newSize, i;

    if (Tcl_IsShared(listPtr)) {
	Tcl_Panic("%s called with shared object", "Tcl_ListObjAppendElement");
    }
    if (listPtr->typePtr != &tclListType) {
	int result, length;
#if 0

	if (listPtr->typePtr == &tclDictType) {
	    (void) Tcl_DictObjSize(NULL, listPtr, &length);
	} else {
	    (void) TclGetStringFromObj(listPtr, &length);
	}
	if (!length) {





	    Tcl_SetListObj(listPtr, 1, &objPtr);
	    return TCL_OK;
	}
#endif
	result = SetListFromAny(interp, listPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }

    listRepPtr = ListRepPtr(listPtr);







<

>






>
>
>
>
>



<







587
588
589
590
591
592
593

594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609

610
611
612
613
614
615
616
    register Tcl_Obj **elemPtrs;
    int numElems, numRequired, newMax, newSize, i;

    if (Tcl_IsShared(listPtr)) {
	Tcl_Panic("%s called with shared object", "Tcl_ListObjAppendElement");
    }
    if (listPtr->typePtr != &tclListType) {

#if 0
	int result, length;
	if (listPtr->typePtr == &tclDictType) {
	    (void) Tcl_DictObjSize(NULL, listPtr, &length);
	} else {
	    (void) TclGetStringFromObj(listPtr, &length);
	}
	if (!length) {
#else
	int result;

	if (listPtr->bytes == tclEmptyStringRep) {
#endif
	    Tcl_SetListObj(listPtr, 1, &objPtr);
	    return TCL_OK;
	}

	result = SetListFromAny(interp, listPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }

    listRepPtr = ListRepPtr(listPtr);
698
699
700
701
702
703
704
705
706

707
708
709
710
711
712





713
714
715
716
717
718
719
720
721
722
723
    register Tcl_Obj *listPtr,	/* List object to index into. */
    register int index,		/* Index of element to return. */
    Tcl_Obj **objPtrPtr)	/* The resulting Tcl_Obj* is stored here. */
{
    register List *listRepPtr;

    if (listPtr->typePtr != &tclListType) {
	int result, length;
#if 0

	if (listPtr->typePtr == &tclDictType) {
	    (void) Tcl_DictObjSize(NULL, listPtr, &length);
	} else {
	    (void) TclGetStringFromObj(listPtr, &length);
	}
	if (!length) {





	    *objPtrPtr = NULL;
	    return TCL_OK;
	}
#endif
	result = SetListFromAny(interp, listPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }

    listRepPtr = ListRepPtr(listPtr);







<

>






>
>
>
>
>



<







706
707
708
709
710
711
712

713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728

729
730
731
732
733
734
735
    register Tcl_Obj *listPtr,	/* List object to index into. */
    register int index,		/* Index of element to return. */
    Tcl_Obj **objPtrPtr)	/* The resulting Tcl_Obj* is stored here. */
{
    register List *listRepPtr;

    if (listPtr->typePtr != &tclListType) {

#if 0
	int result, length;
	if (listPtr->typePtr == &tclDictType) {
	    (void) Tcl_DictObjSize(NULL, listPtr, &length);
	} else {
	    (void) TclGetStringFromObj(listPtr, &length);
	}
	if (!length) {
#else
	int result;

	if (listPtr->bytes == tclEmptyStringRep) {
#endif
	    *objPtrPtr = NULL;
	    return TCL_OK;
	}

	result = SetListFromAny(interp, listPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }

    listRepPtr = ListRepPtr(listPtr);
757
758
759
760
761
762
763
764
765

766
767
768
769
770
771
772
773
774
775
776
777
778
779
780





781
782
783
784
785
786
787
788
789
790
791
    Tcl_Interp *interp,		/* Used to report errors if not NULL. */
    register Tcl_Obj *listPtr,	/* List object whose #elements to return. */
    register int *intPtr)	/* The resulting int is stored here. */
{
    register List *listRepPtr;

    if (listPtr->typePtr != &tclListType) {
	int result, length;
#if 0

	if (listPtr->typePtr == &tclDictType) {
	    (void) Tcl_DictObjSize(NULL, listPtr, &length);
	    /*
	     * It's tempting to just report 2*length as the list length
	     * of this dict, but arguably that's false since the max sizes
	     * for dicts and lists are not the same, so some dicts don't
	     * actually convert to lists, and it's good to get that error
	     * back from the SetListFromAny() call below instead of a false
	     * indication we can treat the value as a list.  ([llength $val]
	     * often used as a "listiness" test)
	     */
	} else {
	    (void) TclGetStringFromObj(listPtr, &length);
	}
	if (!length) {





	    *intPtr = 0;
	    return TCL_OK;
	}
#endif
	result = SetListFromAny(interp, listPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }

    listRepPtr = ListRepPtr(listPtr);







<

>















>
>
>
>
>



<







769
770
771
772
773
774
775

776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800

801
802
803
804
805
806
807
    Tcl_Interp *interp,		/* Used to report errors if not NULL. */
    register Tcl_Obj *listPtr,	/* List object whose #elements to return. */
    register int *intPtr)	/* The resulting int is stored here. */
{
    register List *listRepPtr;

    if (listPtr->typePtr != &tclListType) {

#if 0
	int result, length;
	if (listPtr->typePtr == &tclDictType) {
	    (void) Tcl_DictObjSize(NULL, listPtr, &length);
	    /*
	     * It's tempting to just report 2*length as the list length
	     * of this dict, but arguably that's false since the max sizes
	     * for dicts and lists are not the same, so some dicts don't
	     * actually convert to lists, and it's good to get that error
	     * back from the SetListFromAny() call below instead of a false
	     * indication we can treat the value as a list.  ([llength $val]
	     * often used as a "listiness" test)
	     */
	} else {
	    (void) TclGetStringFromObj(listPtr, &length);
	}
	if (!length) {
#else
	int result;

	if (listPtr->bytes == tclEmptyStringRep) {
#endif
	    *intPtr = 0;
	    return TCL_OK;
	}

	result = SetListFromAny(interp, listPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }

    listRepPtr = ListRepPtr(listPtr);
845
846
847
848
849
850
851
852
853

854
855
856
857
858
859




860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
    register Tcl_Obj **elemPtrs;
    int numElems, numRequired, numAfterLast, start, i, j, isShared;

    if (Tcl_IsShared(listPtr)) {
	Tcl_Panic("%s called with shared object", "Tcl_ListObjReplace");
    }
    if (listPtr->typePtr != &tclListType) {
	int length;
#if 0

	if (listPtr->typePtr == &tclDictType) {
	    (void) Tcl_DictObjSize(NULL, listPtr, &length);
	} else {
	    (void) TclGetStringFromObj(listPtr, &length);
	}
	if (!length) {




	    if (objc) {
		Tcl_SetListObj(listPtr, objc, NULL);
	    } else {
		return TCL_OK;
	    }
	} else {
#endif
	    int result = SetListFromAny(interp, listPtr);

	    if (result != TCL_OK) {
		return result;
	    }
#if 0
	}
#endif
    }

    /*
     * Note that when count == 0 and objc == 0, this routine is logically a
     * no-op, removing and adding no elements to the list. However, by flowing
     * through this routine anyway, we get the important side effect that the
     * resulting listPtr is a list in canoncial form. This is important.







<

>






>
>
>
>






<





<

<







861
862
863
864
865
866
867

868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885

886
887
888
889
890

891

892
893
894
895
896
897
898
    register Tcl_Obj **elemPtrs;
    int numElems, numRequired, numAfterLast, start, i, j, isShared;

    if (Tcl_IsShared(listPtr)) {
	Tcl_Panic("%s called with shared object", "Tcl_ListObjReplace");
    }
    if (listPtr->typePtr != &tclListType) {

#if 0
	int length;
	if (listPtr->typePtr == &tclDictType) {
	    (void) Tcl_DictObjSize(NULL, listPtr, &length);
	} else {
	    (void) TclGetStringFromObj(listPtr, &length);
	}
	if (!length) {
#else
	if (listPtr->bytes == tclEmptyStringRep) {
#endif

	    if (objc) {
		Tcl_SetListObj(listPtr, objc, NULL);
	    } else {
		return TCL_OK;
	    }
	} else {

	    int result = SetListFromAny(interp, listPtr);

	    if (result != TCL_OK) {
		return result;
	    }

	}

    }

    /*
     * Note that when count == 0 and objc == 0, this routine is logically a
     * no-op, removing and adding no elements to the list. However, by flowing
     * through this routine anyway, we get the important side effect that the
     * resulting listPtr is a list in canoncial form. This is important.
1550
1551
1552
1553
1554
1555
1556
1557
1558

1559
1560
1561
1562
1563
1564





1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
     * Ensure that the listPtr parameter designates an unshared list.
     */

    if (Tcl_IsShared(listPtr)) {
	Tcl_Panic("%s called with shared object", "TclListObjSetElement");
    }
    if (listPtr->typePtr != &tclListType) {
	int length, result;
#if 0

	if (listPtr->typePtr == &tclDictType) {
	    (void) Tcl_DictObjSize(NULL, listPtr, &length);
	} else {
	    (void) TclGetStringFromObj(listPtr, &length);
	}
	if (!length) {





	    if (interp != NULL) {
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj("list index out of range", -1));
	    }
	    return TCL_ERROR;
	}
#endif
	result = SetListFromAny(interp, listPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }

    listRepPtr = ListRepPtr(listPtr);







<

>






>
>
>
>
>






<







1567
1568
1569
1570
1571
1572
1573

1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592

1593
1594
1595
1596
1597
1598
1599
     * Ensure that the listPtr parameter designates an unshared list.
     */

    if (Tcl_IsShared(listPtr)) {
	Tcl_Panic("%s called with shared object", "TclListObjSetElement");
    }
    if (listPtr->typePtr != &tclListType) {

#if 0
	int length, result;
	if (listPtr->typePtr == &tclDictType) {
	    (void) Tcl_DictObjSize(NULL, listPtr, &length);
	} else {
	    (void) TclGetStringFromObj(listPtr, &length);
	}
	if (!length) {
#else
	int result;

	if (listPtr->bytes == tclEmptyStringRep) {
#endif
	    if (interp != NULL) {
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj("list index out of range", -1));
	    }
	    return TCL_ERROR;
	}

	result = SetListFromAny(interp, listPtr);
	if (result != TCL_OK) {
	    return result;
	}
    }

    listRepPtr = ListRepPtr(listPtr);